From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- dom/security/test/cors/browser.toml | 10 + .../test/cors/browser_CORS-console-warnings.js | 101 ++ dom/security/test/cors/bug1456721.sjs | 20 + .../test/cors/file_CrossSiteXHR_cache_server.sjs | 59 + .../test/cors/file_CrossSiteXHR_inner.html | 121 ++ dom/security/test/cors/file_CrossSiteXHR_inner.jar | Bin 0 -> 1105 bytes .../test/cors/file_CrossSiteXHR_inner_data.sjs | 103 ++ .../test/cors/file_CrossSiteXHR_server.sjs | 230 +++ dom/security/test/cors/file_bug1456721.html | 74 + dom/security/test/cors/file_cors_logging_test.html | 1311 +++++++++++++++++ .../test/cors/file_cors_logging_test.html.css | 0 dom/security/test/cors/mochitest.toml | 26 + dom/security/test/cors/test_CrossSiteXHR.html | 1549 ++++++++++++++++++++ .../test/cors/test_CrossSiteXHR_cache.html | 610 ++++++++ .../test/cors/test_CrossSiteXHR_origin.html | 180 +++ dom/security/test/crashtests/1577572.html | 10 + dom/security/test/crashtests/1583044.html | 11 + dom/security/test/crashtests/crashtests.list | 2 + dom/security/test/csp/Ahem.ttf | Bin 0 -> 12480 bytes dom/security/test/csp/File | 0 dom/security/test/csp/browser.toml | 30 + .../browser_manifest-src-override-default-src.js | 126 ++ .../test/csp/browser_pdfjs_not_subject_to_csp.js | 45 + dom/security/test/csp/browser_test_bookmarklets.js | 82 ++ .../test/csp/browser_test_uir_optional_clicks.js | 36 + dom/security/test/csp/browser_test_web_manifest.js | 239 +++ .../csp/browser_test_web_manifest_mixed_content.js | 57 + dom/security/test/csp/dummy.pdf | Bin 0 -> 150611 bytes dom/security/test/csp/file_CSP.css | 20 + dom/security/test/csp/file_CSP.sjs | 24 + .../test/csp/file_allow_https_schemes.html | 14 + dom/security/test/csp/file_base_uri_server.sjs | 58 + dom/security/test/csp/file_blob_data_schemes.html | 49 + .../test/csp/file_blob_top_nav_block_modals.html | 18 + .../file_blob_top_nav_block_modals.html^headers^ | 1 + .../test/csp/file_blob_uri_blocks_modals.html | 27 + .../csp/file_blob_uri_blocks_modals.html^headers^ | 1 + dom/security/test/csp/file_block_all_mcb.sjs | 78 + ..._block_all_mixed_content_frame_navigation1.html | 19 + ..._block_all_mixed_content_frame_navigation2.html | 15 + ...ked_uri_in_violation_event_after_redirects.html | 39 + ...cked_uri_in_violation_event_after_redirects.sjs | 51 + .../csp/file_blocked_uri_redirect_frame_src.html | 10 + ...le_blocked_uri_redirect_frame_src.html^headers^ | 1 + .../file_blocked_uri_redirect_frame_src_server.sjs | 13 + dom/security/test/csp/file_bug1229639.html | 7 + .../test/csp/file_bug1229639.html^headers^ | 1 + dom/security/test/csp/file_bug1312272.html | 13 + .../test/csp/file_bug1312272.html^headers^ | 1 + dom/security/test/csp/file_bug1312272.js | 8 + dom/security/test/csp/file_bug1452037.html | 9 + dom/security/test/csp/file_bug1505412.sjs | 34 + dom/security/test/csp/file_bug1505412_frame.html | 14 + .../test/csp/file_bug1505412_frame.html^headers^ | 1 + dom/security/test/csp/file_bug1505412_reporter.sjs | 18 + dom/security/test/csp/file_bug1738418_child.html | 11 + dom/security/test/csp/file_bug1738418_parent.html | 11 + .../test/csp/file_bug1738418_parent.html^headers^ | 1 + dom/security/test/csp/file_bug1764343.html | 11 + dom/security/test/csp/file_bug1777572.html | 43 + dom/security/test/csp/file_bug663567.xsl | 27 + dom/security/test/csp/file_bug663567_allows.xml | 28 + .../test/csp/file_bug663567_allows.xml^headers^ | 1 + dom/security/test/csp/file_bug663567_blocks.xml | 28 + .../test/csp/file_bug663567_blocks.xml^headers^ | 1 + dom/security/test/csp/file_bug802872.html | 12 + dom/security/test/csp/file_bug802872.html^headers^ | 1 + dom/security/test/csp/file_bug802872.js | 47 + dom/security/test/csp/file_bug802872.sjs | 6 + .../test/csp/file_bug836922_npolicies.html | 12 + .../csp/file_bug836922_npolicies.html^headers^ | 2 + .../csp/file_bug836922_npolicies_ro_violation.sjs | 53 + .../csp/file_bug836922_npolicies_violation.sjs | 64 + dom/security/test/csp/file_bug885433_allows.html | 39 + .../test/csp/file_bug885433_allows.html^headers^ | 1 + dom/security/test/csp/file_bug885433_blocks.html | 38 + .../test/csp/file_bug885433_blocks.html^headers^ | 1 + dom/security/test/csp/file_bug886164.html | 15 + dom/security/test/csp/file_bug886164.html^headers^ | 1 + dom/security/test/csp/file_bug886164_2.html | 14 + .../test/csp/file_bug886164_2.html^headers^ | 1 + dom/security/test/csp/file_bug886164_3.html | 12 + .../test/csp/file_bug886164_3.html^headers^ | 1 + dom/security/test/csp/file_bug886164_4.html | 12 + .../test/csp/file_bug886164_4.html^headers^ | 1 + dom/security/test/csp/file_bug886164_5.html | 26 + .../test/csp/file_bug886164_5.html^headers^ | 1 + dom/security/test/csp/file_bug886164_6.html | 35 + .../test/csp/file_bug886164_6.html^headers^ | 1 + dom/security/test/csp/file_bug888172.html | 29 + dom/security/test/csp/file_bug888172.sjs | 49 + dom/security/test/csp/file_bug909029_none.html | 20 + .../test/csp/file_bug909029_none.html^headers^ | 1 + dom/security/test/csp/file_bug909029_star.html | 19 + .../test/csp/file_bug909029_star.html^headers^ | 1 + dom/security/test/csp/file_bug910139.sjs | 56 + dom/security/test/csp/file_bug910139.xml | 28 + dom/security/test/csp/file_bug910139.xsl | 27 + dom/security/test/csp/file_bug941404.html | 27 + dom/security/test/csp/file_bug941404_xhr.html | 5 + .../test/csp/file_bug941404_xhr.html^headers^ | 1 + dom/security/test/csp/file_child-src_iframe.html | 61 + .../test/csp/file_child-src_inner_frame.html | 21 + .../test/csp/file_child-src_service_worker.html | 30 + .../test/csp/file_child-src_service_worker.js | 3 + .../csp/file_child-src_shared_worker-redirect.html | 47 + .../test/csp/file_child-src_shared_worker.html | 35 + .../test/csp/file_child-src_shared_worker.js | 8 + .../csp/file_child-src_shared_worker_data.html | 37 + .../test/csp/file_child-src_worker-redirect.html | 47 + dom/security/test/csp/file_child-src_worker.html | 34 + dom/security/test/csp/file_child-src_worker.js | 3 + .../test/csp/file_child-src_worker_data.html | 33 + dom/security/test/csp/file_connect-src-fetch.html | 16 + dom/security/test/csp/file_connect-src.html | 21 + .../csp/file_csp_frame_ancestors_about_blank.html | 9 + ...e_csp_frame_ancestors_about_blank.html^headers^ | 2 + dom/security/test/csp/file_csp_meta_uir.html | 13 + dom/security/test/csp/file_data-uri_blocked.html | 15 + .../test/csp/file_data-uri_blocked.html^headers^ | 1 + .../test/csp/file_data_csp_inheritance.html | 24 + dom/security/test/csp/file_data_csp_merge.html | 26 + .../test/csp/file_data_doc_ignore_meta_csp.html | 22 + dom/security/test/csp/file_doccomment_meta.html | 28 + dom/security/test/csp/file_docwrite_meta.css | 3 + dom/security/test/csp/file_docwrite_meta.html | 26 + dom/security/test/csp/file_docwrite_meta.js | 3 + .../test/csp/file_dual_header_testserver.sjs | 45 + dom/security/test/csp/file_dummy_pixel.png | Bin 0 -> 70 bytes dom/security/test/csp/file_empty_directive.html | 11 + .../test/csp/file_empty_directive.html^headers^ | 1 + dom/security/test/csp/file_evalscript_main.html | 12 + .../test/csp/file_evalscript_main.html^headers^ | 2 + dom/security/test/csp/file_evalscript_main.js | 243 +++ .../test/csp/file_evalscript_main_allowed.html | 12 + .../csp/file_evalscript_main_allowed.html^headers^ | 2 + .../test/csp/file_evalscript_main_allowed.js | 195 +++ dom/security/test/csp/file_fontloader.sjs | 57 + dom/security/test/csp/file_fontloader.woff | Bin 0 -> 11140 bytes dom/security/test/csp/file_form-action.html | 15 + dom/security/test/csp/file_form_action_server.sjs | 32 + dom/security/test/csp/file_frame_ancestors_ro.html | 1 + .../test/csp/file_frame_ancestors_ro.html^headers^ | 1 + dom/security/test/csp/file_frame_src.js | 20 + .../test/csp/file_frame_src_child_governs.html | 10 + .../test/csp/file_frame_src_frame_governs.html | 10 + dom/security/test/csp/file_frame_src_inner.html | 5 + dom/security/test/csp/file_frameancestors.sjs | 69 + .../test/csp/file_frameancestors_main.html | 44 + dom/security/test/csp/file_frameancestors_main.js | 134 ++ .../test/csp/file_frameancestors_userpass.html | 10 + .../csp/file_frameancestors_userpass_frame_a.html | 12 + .../csp/file_frameancestors_userpass_frame_b.html | 12 + .../csp/file_frameancestors_userpass_frame_c.html | 8 + ...e_frameancestors_userpass_frame_c.html^headers^ | 1 + .../csp/file_frameancestors_userpass_frame_d.html | 8 + ...e_frameancestors_userpass_frame_d.html^headers^ | 1 + dom/security/test/csp/file_hash_source.html | 65 + .../test/csp/file_hash_source.html^headers^ | 2 + .../test/csp/file_iframe_parent_location_js.html | 10 + .../csp/file_iframe_sandbox_document_write.html | 21 + .../test/csp/file_iframe_sandbox_srcdoc.html | 11 + .../csp/file_iframe_sandbox_srcdoc.html^headers^ | 1 + dom/security/test/csp/file_iframe_srcdoc.sjs | 86 ++ .../test/csp/file_ignore_unsafe_inline.html | 26 + ...nore_unsafe_inline_multiple_policies_server.sjs | 58 + dom/security/test/csp/file_ignore_xfo.html | 10 + .../test/csp/file_ignore_xfo.html^headers^ | 3 + .../test/csp/file_image_document_pixel.png | Bin 0 -> 70 bytes .../csp/file_image_document_pixel.png^headers^ | 2 + dom/security/test/csp/file_image_nonce.html | 39 + .../test/csp/file_image_nonce.html^headers^ | 2 + .../test/csp/file_independent_iframe_csp.html | 43 + dom/security/test/csp/file_inlinescript.html | 15 + dom/security/test/csp/file_inlinestyle_main.html | 79 + .../test/csp/file_inlinestyle_main.html^headers^ | 2 + .../test/csp/file_inlinestyle_main_allowed.html | 84 ++ .../file_inlinestyle_main_allowed.html^headers^ | 2 + .../test/csp/file_invalid_source_expression.html | 11 + dom/security/test/csp/file_leading_wildcard.html | 11 + dom/security/test/csp/file_link_rel_preload.html | 19 + dom/security/test/csp/file_main.html | 55 + dom/security/test/csp/file_main.html^headers^ | 1 + dom/security/test/csp/file_main.js | 26 + dom/security/test/csp/file_meta_element.html | 27 + dom/security/test/csp/file_meta_header_dual.sjs | 101 ++ .../test/csp/file_meta_whitespace_skipping.html | 31 + .../csp/file_multi_policy_injection_bypass.html | 15 + ...ile_multi_policy_injection_bypass.html^headers^ | 1 + .../csp/file_multi_policy_injection_bypass_2.html | 15 + ...e_multi_policy_injection_bypass_2.html^headers^ | 1 + .../test/csp/file_multipart_testserver.sjs | 160 ++ dom/security/test/csp/file_no_log_ignore_xfo.html | 10 + .../test/csp/file_no_log_ignore_xfo.html^headers^ | 2 + dom/security/test/csp/file_nonce_redirector.sjs | 28 + dom/security/test/csp/file_nonce_redirects.html | 23 + dom/security/test/csp/file_nonce_snapshot.sjs | 54 + dom/security/test/csp/file_nonce_source.html | 73 + .../test/csp/file_nonce_source.html^headers^ | 2 + dom/security/test/csp/file_null_baseuri.html | 21 + dom/security/test/csp/file_object_inherit.html | 21 + dom/security/test/csp/file_parent_location_js.html | 18 + dom/security/test/csp/file_path_matching.html | 10 + dom/security/test/csp/file_path_matching.js | 1 + .../test/csp/file_path_matching_incl_query.html | 10 + .../test/csp/file_path_matching_redirect.html | 10 + .../csp/file_path_matching_redirect_server.sjs | 12 + .../test/csp/file_pdfjs_not_subject_to_csp.html | 21 + dom/security/test/csp/file_ping.html | 19 + ...file_policyuri_regression_from_multipolicy.html | 9 + ...cyuri_regression_from_multipolicy.html^headers^ | 1 + ...le_policyuri_regression_from_multipolicy_policy | 1 + dom/security/test/csp/file_punycode_host_src.js | 2 + dom/security/test/csp/file_punycode_host_src.sjs | 46 + dom/security/test/csp/file_redirect_content.sjs | 39 + dom/security/test/csp/file_redirect_report.sjs | 16 + dom/security/test/csp/file_redirect_worker.sjs | 34 + dom/security/test/csp/file_redirects_main.html | 37 + dom/security/test/csp/file_redirects_page.sjs | 140 ++ dom/security/test/csp/file_redirects_resource.sjs | 171 +++ dom/security/test/csp/file_report.html | 13 + dom/security/test/csp/file_report_chromescript.js | 68 + .../test/csp/file_report_font_cache-1.html | 26 + .../test/csp/file_report_font_cache-2.html | 25 + .../csp/file_report_font_cache-2.html^headers^ | 1 + dom/security/test/csp/file_report_for_import.css | 1 + dom/security/test/csp/file_report_for_import.html | 10 + .../test/csp/file_report_for_import_server.sjs | 50 + ...e_report_uri_missing_in_report_only_header.html | 0 ...uri_missing_in_report_only_header.html^headers^ | 1 + dom/security/test/csp/file_ro_ignore_xfo.html | 10 + .../test/csp/file_ro_ignore_xfo.html^headers^ | 3 + dom/security/test/csp/file_sandbox_1.html | 16 + dom/security/test/csp/file_sandbox_10.html | 12 + dom/security/test/csp/file_sandbox_11.html | 25 + dom/security/test/csp/file_sandbox_12.html | 40 + dom/security/test/csp/file_sandbox_13.html | 25 + dom/security/test/csp/file_sandbox_2.html | 16 + dom/security/test/csp/file_sandbox_3.html | 13 + dom/security/test/csp/file_sandbox_4.html | 13 + dom/security/test/csp/file_sandbox_5.html | 26 + dom/security/test/csp/file_sandbox_6.html | 35 + dom/security/test/csp/file_sandbox_7.html | 15 + dom/security/test/csp/file_sandbox_8.html | 15 + dom/security/test/csp/file_sandbox_9.html | 12 + .../test/csp/file_sandbox_allow_scripts.html | 12 + .../csp/file_sandbox_allow_scripts.html^headers^ | 1 + dom/security/test/csp/file_sandbox_fail.js | 7 + dom/security/test/csp/file_sandbox_pass.js | 7 + .../test/csp/file_scheme_relative_sources.js | 1 + .../test/csp/file_scheme_relative_sources.sjs | 44 + dom/security/test/csp/file_script_template.html | 16 + dom/security/test/csp/file_script_template.js | 1 + .../csp/file_self_none_as_hostname_confusion.html | 11 + ...e_self_none_as_hostname_confusion.html^headers^ | 1 + dom/security/test/csp/file_sendbeacon.html | 21 + dom/security/test/csp/file_service_worker.html | 21 + dom/security/test/csp/file_service_worker.js | 1 + dom/security/test/csp/file_spawn_service_worker.js | 1 + dom/security/test/csp/file_spawn_shared_worker.js | 7 + dom/security/test/csp/file_spawn_worker.js | 1 + dom/security/test/csp/file_strict_dynamic.js | 1 + .../test/csp/file_strict_dynamic_default_src.html | 20 + .../test/csp/file_strict_dynamic_default_src.js | 1 + .../test/csp/file_strict_dynamic_js_url.html | 15 + .../file_strict_dynamic_non_parser_inserted.html | 17 + ..._strict_dynamic_non_parser_inserted_inline.html | 16 + ...e_strict_dynamic_parser_inserted_doc_write.html | 15 + ...ic_parser_inserted_doc_write_correct_nonce.html | 15 + .../csp/file_strict_dynamic_script_events.html | 14 + .../file_strict_dynamic_script_events_marquee.html | 14 + .../csp/file_strict_dynamic_script_extern.html | 10 + .../csp/file_strict_dynamic_script_inline.html | 14 + .../test/csp/file_strict_dynamic_unsafe_eval.html | 15 + .../test/csp/file_subframe_run_js_if_allowed.html | 13 + .../file_subframe_run_js_if_allowed.html^headers^ | 1 + .../test/csp/file_svg_inline_style_base.html | 9 + .../test/csp/file_svg_inline_style_csp.html | 10 + .../test/csp/file_svg_inline_style_server.sjs | 43 + .../csp/file_svg_srcset_inline_style_base.html | 9 + .../test/csp/file_svg_srcset_inline_style_csp.html | 10 + .../test/csp/file_test_browser_bookmarklets.html | 12 + .../file_test_browser_bookmarklets.html^headers^ | 2 + dom/security/test/csp/file_testserver.sjs | 66 + dom/security/test/csp/file_uir_top_nav.html | 17 + dom/security/test/csp/file_uir_top_nav_dummy.html | 12 + dom/security/test/csp/file_upgrade_insecure.html | 90 ++ .../test/csp/file_upgrade_insecure_cors.html | 49 + .../test/csp/file_upgrade_insecure_cors_server.sjs | 61 + .../csp/file_upgrade_insecure_docwrite_iframe.sjs | 55 + .../test/csp/file_upgrade_insecure_loopback.html | 25 + .../csp/file_upgrade_insecure_loopback_form.html | 17 + .../csp/file_upgrade_insecure_loopback_server.sjs | 22 + .../test/csp/file_upgrade_insecure_meta.html | 86 ++ .../test/csp/file_upgrade_insecure_navigation.sjs | 78 + .../file_upgrade_insecure_navigation_redirect.sjs | 50 + ..._insecure_navigation_redirect_cross_origin.html | 10 + ...e_insecure_navigation_redirect_same_origin.html | 10 + .../csp/file_upgrade_insecure_report_only.html | 33 + .../file_upgrade_insecure_report_only_server.sjs | 114 ++ .../test/csp/file_upgrade_insecure_reporting.html | 23 + .../csp/file_upgrade_insecure_reporting_server.sjs | 89 ++ .../test/csp/file_upgrade_insecure_server.sjs | 112 ++ dom/security/test/csp/file_upgrade_insecure_wsh.py | 6 + dom/security/test/csp/file_web_manifest.html | 6 + dom/security/test/csp/file_web_manifest.json | 1 + .../test/csp/file_web_manifest.json^headers^ | 1 + dom/security/test/csp/file_web_manifest_https.html | 4 + dom/security/test/csp/file_web_manifest_https.json | 1 + .../test/csp/file_web_manifest_mixed_content.html | 9 + .../test/csp/file_web_manifest_remote.html | 8 + .../test/csp/file_websocket_csp_upgrade.html | 20 + dom/security/test/csp/file_websocket_explicit.html | 31 + dom/security/test/csp/file_websocket_self.html | 31 + dom/security/test/csp/file_websocket_self_wsh.py | 6 + dom/security/test/csp/file_win_open_blocked.html | 3 + .../test/csp/file_windowwatcher_frameA.html | 17 + .../test/csp/file_windowwatcher_subframeB.html | 12 + .../test/csp/file_windowwatcher_subframeC.html | 9 + .../test/csp/file_windowwatcher_subframeD.html | 6 + .../test/csp/file_windowwatcher_win_open.html | 15 + dom/security/test/csp/file_worker_src.js | 73 + .../test/csp/file_worker_src_child_governs.html | 9 + .../test/csp/file_worker_src_script_governs.html | 9 + .../test/csp/file_worker_src_worker_governs.html | 9 + dom/security/test/csp/file_xslt_inherits_csp.xml | 6 + .../test/csp/file_xslt_inherits_csp.xml^headers^ | 2 + dom/security/test/csp/file_xslt_inherits_csp.xsl | 26 + dom/security/test/csp/main_csp_worker.html | 439 ++++++ .../test/csp/main_csp_worker.html^headers^ | 1 + dom/security/test/csp/mochitest.toml | 821 +++++++++++ dom/security/test/csp/referrerdirective.sjs | 40 + dom/security/test/csp/test_301_redirect.html | 74 + dom/security/test/csp/test_302_redirect.html | 74 + dom/security/test/csp/test_303_redirect.html | 74 + dom/security/test/csp/test_307_redirect.html | 75 + dom/security/test/csp/test_CSP.html | 130 ++ .../test/csp/test_allow_https_schemes.html | 76 + dom/security/test/csp/test_base-uri.html | 124 ++ dom/security/test/csp/test_blob_data_schemes.html | 89 ++ .../test/csp/test_blob_uri_blocks_modals.html | 75 + .../test/csp/test_block_all_mixed_content.html | 99 ++ ...t_block_all_mixed_content_frame_navigation.html | 46 + .../test/csp/test_blocked_uri_in_reports.html | 80 + ...ked_uri_in_violation_event_after_redirects.html | 56 + .../csp/test_blocked_uri_redirect_frame_src.html | 60 + dom/security/test/csp/test_bug1229639.html | 51 + dom/security/test/csp/test_bug1242019.html | 51 + dom/security/test/csp/test_bug1312272.html | 32 + dom/security/test/csp/test_bug1388015.html | 46 + dom/security/test/csp/test_bug1452037.html | 41 + dom/security/test/csp/test_bug1505412.html | 50 + dom/security/test/csp/test_bug1579094.html | 31 + dom/security/test/csp/test_bug1738418.html | 28 + dom/security/test/csp/test_bug1764343.html | 116 ++ dom/security/test/csp/test_bug1777572.html | 40 + dom/security/test/csp/test_bug663567.html | 76 + dom/security/test/csp/test_bug802872.html | 53 + .../test/csp/test_bug836922_npolicies.html | 235 +++ dom/security/test/csp/test_bug885433.html | 61 + dom/security/test/csp/test_bug886164.html | 172 +++ dom/security/test/csp/test_bug888172.html | 73 + dom/security/test/csp/test_bug909029.html | 129 ++ dom/security/test/csp/test_bug910139.html | 66 + dom/security/test/csp/test_bug941404.html | 107 ++ dom/security/test/csp/test_child-src_iframe.html | 113 ++ .../test/csp/test_child-src_worker-redirect.html | 125 ++ dom/security/test/csp/test_child-src_worker.html | 147 ++ .../test/csp/test_child-src_worker_data.html | 126 ++ dom/security/test/csp/test_connect-src.html | 129 ++ .../csp/test_csp_frame_ancestors_about_blank.html | 59 + .../test/csp/test_csp_style_src_empty_hash.html | 32 + .../test/csp/test_csp_worker_inheritance.html | 20 + .../test/csp/test_data_csp_inheritance.html | 36 + dom/security/test/csp/test_data_csp_merge.html | 36 + .../test/csp/test_data_doc_ignore_meta_csp.html | 39 + dom/security/test/csp/test_docwrite_meta.html | 86 ++ dom/security/test/csp/test_dual_header.html | 66 + dom/security/test/csp/test_empty_directive.html | 51 + dom/security/test/csp/test_evalscript.html | 59 + .../test_evalscript_allowed_by_strict_dynamic.html | 37 + .../test_evalscript_blocked_by_strict_dynamic.html | 37 + dom/security/test/csp/test_fontloader.html | 98 ++ dom/security/test/csp/test_form-action.html | 105 ++ .../test/csp/test_form_action_blocks_url.html | 76 + dom/security/test/csp/test_frame_ancestors_ro.html | 69 + dom/security/test/csp/test_frame_src.html | 84 ++ dom/security/test/csp/test_frameancestors.html | 160 ++ .../test/csp/test_frameancestors_userpass.html | 148 ++ dom/security/test/csp/test_hash_source.html | 135 ++ dom/security/test/csp/test_iframe_sandbox.html | 240 +++ .../test/csp/test_iframe_sandbox_srcdoc.html | 62 + .../test/csp/test_iframe_sandbox_top_1.html | 80 + .../csp/test_iframe_sandbox_top_1.html^headers^ | 1 + dom/security/test/csp/test_iframe_srcdoc.html | 140 ++ .../test/csp/test_ignore_unsafe_inline.html | 122 ++ dom/security/test/csp/test_ignore_xfo.html | 120 ++ dom/security/test/csp/test_image_document.html | 35 + dom/security/test/csp/test_image_nonce.html | 60 + .../test/csp/test_independent_iframe_csp.html | 79 + dom/security/test/csp/test_inlinescript.html | 123 ++ dom/security/test/csp/test_inlinestyle.html | 107 ++ .../test/csp/test_invalid_source_expression.html | 57 + dom/security/test/csp/test_leading_wildcard.html | 101 ++ dom/security/test/csp/test_link_rel_preload.html | 73 + dom/security/test/csp/test_meta_csp_self.html | 63 + dom/security/test/csp/test_meta_element.html | 91 ++ dom/security/test/csp/test_meta_header_dual.html | 135 ++ .../test/csp/test_meta_whitespace_skipping.html | 81 + .../csp/test_multi_policy_injection_bypass.html | 119 ++ dom/security/test/csp/test_multipartchannel.html | 68 + dom/security/test/csp/test_nonce_redirects.html | 47 + dom/security/test/csp/test_nonce_snapshot.html | 35 + dom/security/test/csp/test_nonce_source.html | 122 ++ dom/security/test/csp/test_null_baseuri.html | 67 + dom/security/test/csp/test_object_inherit.html | 30 + dom/security/test/csp/test_parent_location_js.html | 38 + dom/security/test/csp/test_path_matching.html | 115 ++ .../test/csp/test_path_matching_redirect.html | 89 ++ dom/security/test/csp/test_ping.html | 103 ++ ...test_policyuri_regression_from_multipolicy.html | 27 + dom/security/test/csp/test_punycode_host_src.html | 81 + dom/security/test/csp/test_redirects.html | 142 ++ dom/security/test/csp/test_report.html | 113 ++ dom/security/test/csp/test_report_font_cache.html | 56 + dom/security/test/csp/test_report_for_import.html | 109 ++ ...t_report_uri_missing_in_report_only_header.html | 54 + dom/security/test/csp/test_sandbox.html | 249 ++++ .../test/csp/test_sandbox_allow_scripts.html | 31 + .../test/csp/test_scheme_relative_sources.html | 91 ++ dom/security/test/csp/test_script_template.html | 60 + .../csp/test_security_policy_violation_event.html | 15 + .../csp/test_self_none_as_hostname_confusion.html | 53 + dom/security/test/csp/test_sendbeacon.html | 34 + dom/security/test/csp/test_service_worker.html | 61 + dom/security/test/csp/test_strict_dynamic.html | 133 ++ .../test/csp/test_strict_dynamic_default_src.html | 136 ++ .../csp/test_strict_dynamic_parser_inserted.html | 94 ++ .../test/csp/test_subframe_run_js_if_allowed.html | 33 + dom/security/test/csp/test_svg_inline_style.html | 135 ++ dom/security/test/csp/test_uir_top_nav.html | 53 + dom/security/test/csp/test_uir_windowwatcher.html | 31 + dom/security/test/csp/test_upgrade_insecure.html | 192 +++ .../test/csp/test_upgrade_insecure_cors.html | 86 ++ .../csp/test_upgrade_insecure_docwrite_iframe.html | 54 + .../test/csp/test_upgrade_insecure_loopback.html | 91 ++ .../test/csp/test_upgrade_insecure_navigation.html | 105 ++ .../test_upgrade_insecure_navigation_redirect.html | 66 + .../csp/test_upgrade_insecure_report_only.html | 98 ++ .../test/csp/test_upgrade_insecure_reporting.html | 69 + .../test/csp/test_websocket_localhost.html | 40 + dom/security/test/csp/test_websocket_self.html | 61 + dom/security/test/csp/test_win_open_blocked.html | 52 + dom/security/test/csp/test_worker_src.html | 105 ++ dom/security/test/csp/test_xslt_inherits_csp.html | 33 + dom/security/test/csp/worker.sjs | 111 ++ dom/security/test/csp/worker_helper.js | 91 ++ dom/security/test/general/browser.toml | 81 + .../test/general/browser_file_nonscript.js | 38 + .../browser_restrict_privileged_about_script.js | 70 + .../browser_same_site_cookies_bug1748693.js | 61 + ...rowser_test_assert_systemprincipal_documents.js | 41 + .../test/general/browser_test_data_download.js | 113 ++ .../test/general/browser_test_data_text_csv.js | 108 ++ .../general/browser_test_framing_error_pages.js | 53 + .../browser_test_gpc_privateBrowsingMode.js | 67 + .../browser_test_referrer_loadInOtherProcess.js | 156 ++ .../test/general/browser_test_report_blocking.js | 218 +++ .../browser_test_toplevel_data_navigations.js | 70 + .../browser_test_view_image_data_navigation.js | 71 + .../test/general/browser_test_xfo_embed_object.js | 41 + dom/security/test/general/bug1277803.html | 11 + dom/security/test/general/chrome.toml | 15 + dom/security/test/general/closeWindow.sjs | 24 + dom/security/test/general/favicon_bug1277803.ico | Bin 0 -> 1406 bytes dom/security/test/general/file_1767581.js | 1 + dom/security/test/general/file_about_child.html | 11 + .../file_assert_systemprincipal_documents.html | 11 + ...le_assert_systemprincipal_documents_iframe.html | 9 + .../file_block_script_wrong_mime_server.sjs | 37 + .../file_block_subresource_redir_to_data.sjs | 33 + .../file_block_toplevel_data_navigation.html | 16 + .../file_block_toplevel_data_navigation2.html | 17 + .../file_block_toplevel_data_navigation3.html | 16 + .../general/file_block_toplevel_data_redirect.sjs | 13 + .../test/general/file_cache_splitting_isloaded.sjs | 35 + .../test/general/file_cache_splitting_server.sjs | 27 + .../test/general/file_cache_splitting_window.html | 17 + ...file_contentpolicytype_targeted_link_iframe.sjs | 45 + dom/security/test/general/file_data_download.html | 14 + dom/security/test/general/file_data_text_csv.html | 14 + dom/security/test/general/file_empty.html | 1 + .../test/general/file_framing_error_pages.sjs | 27 + .../test/general/file_framing_error_pages_csp.html | 7 + .../test/general/file_framing_error_pages_xfo.html | 7 + .../test/general/file_framing_xfo_embed.html | 7 + .../test/general/file_framing_xfo_embed_object.sjs | 7 + .../test/general/file_framing_xfo_object.html | 7 + dom/security/test/general/file_gpc_server.sjs | 14 + .../test/general/file_loads_nonscript.html | 49 + .../test/general/file_meta_referrer_in_head.html | 13 + .../general/file_meta_referrer_notin_head.html | 14 + dom/security/test/general/file_nonscript | 1 + dom/security/test/general/file_nonscript.html | 1 + dom/security/test/general/file_nonscript.json | 1 + dom/security/test/general/file_nonscript.txt | 1 + dom/security/test/general/file_nonscript.xyz | 1 + .../test/general/file_nosniff_navigation.sjs | 39 + .../test/general/file_nosniff_testserver.sjs | 60 + .../test/general/file_same_site_cookies_about.sjs | 99 ++ ...le_same_site_cookies_blob_iframe_inclusion.html | 34 + ...e_same_site_cookies_blob_iframe_navigation.html | 30 + .../general/file_same_site_cookies_bug1748693.sjs | 31 + ...file_same_site_cookies_cross_origin_context.sjs | 54 + .../general/file_same_site_cookies_from_script.sjs | 48 + .../test/general/file_same_site_cookies_iframe.sjs | 99 ++ .../general/file_same_site_cookies_redirect.sjs | 103 ++ .../general/file_same_site_cookies_subrequest.sjs | 82 ++ .../file_same_site_cookies_toplevel_nav.sjs | 96 ++ .../file_same_site_cookies_toplevel_set_cookie.sjs | 68 + dom/security/test/general/file_script.js | 1 + .../general/file_toplevel_data_meta_redirect.html | 10 + .../general/file_toplevel_data_navigations.sjs | 13 + .../file_view_bg_image_data_navigation.html | 16 + .../general/file_view_image_data_navigation.html | 12 + dom/security/test/general/file_xfo_error_page.sjs | 8 + dom/security/test/general/mochitest.toml | 148 ++ .../test/general/test_allow_opening_data_json.html | 39 + .../test/general/test_allow_opening_data_pdf.html | 41 + .../general/test_assert_about_page_no_csp.html | 30 + .../test/general/test_block_script_wrong_mime.html | 92 ++ .../test_block_subresource_redir_to_data.html | 66 + .../test_block_toplevel_data_img_navigation.html | 53 + .../test_block_toplevel_data_navigation.html | 134 ++ dom/security/test/general/test_bug1277803.xhtml | 65 + dom/security/test/general/test_bug1450853.html | 91 ++ .../test/general/test_bug1660452_http.html | 39 + .../test/general/test_bug1660452_https.html | 39 + dom/security/test/general/test_cache_split.html | 153 ++ ...est_contentpolicytype_targeted_link_iframe.html | 103 ++ dom/security/test/general/test_gpc.html | 51 + .../test/general/test_innerhtml_sanitizer.html | 74 + .../test/general/test_innerhtml_sanitizer.xhtml | 73 + dom/security/test/general/test_meta_referrer.html | 55 + dom/security/test/general/test_nosniff.html | 88 ++ .../test/general/test_nosniff_navigation.html | 35 + .../test/general/test_same_site_cookies_about.html | 116 ++ ...est_same_site_cookies_cross_origin_context.html | 93 ++ .../test_same_site_cookies_from_script.html | 86 ++ .../general/test_same_site_cookies_iframe.html | 168 +++ .../test_same_site_cookies_laxByDefault.html | 85 ++ .../general/test_same_site_cookies_redirect.html | 101 ++ .../general/test_same_site_cookies_subrequest.html | 113 ++ .../test_same_site_cookies_toplevel_nav.html | 117 ++ ...test_same_site_cookies_toplevel_set_cookie.html | 57 + dom/security/test/general/test_xfo_error_page.html | 35 + .../test/general/window_nosniff_navigation.html | 96 ++ dom/security/test/gtest/TestCSPParser.cpp | 1148 +++++++++++++++ dom/security/test/gtest/TestFilenameEvalParser.cpp | 453 ++++++ dom/security/test/gtest/TestSecureContext.cpp | 121 ++ dom/security/test/gtest/TestSmartCrashTrimmer.cpp | 44 + .../test/gtest/TestUnexpectedPrivilegedLoads.cpp | 305 ++++ dom/security/test/gtest/moz.build | 25 + dom/security/test/https-first/browser.toml | 53 + .../browser_beforeunload_permit_http.js | 208 +++ ...downgrade_mixed_content_auto_upgrade_console.js | 82 ++ .../https-first/browser_downgrade_view_source.js | 81 + .../test/https-first/browser_download_attribute.js | 125 ++ .../test/https-first/browser_httpsfirst.js | 74 + .../browser_httpsfirst_console_logging.js | 72 + .../browser_httpsfirst_speculative_connect.js | 71 + .../https-first/browser_mixed_content_console.js | 104 ++ .../https-first/browser_mixed_content_download.js | 156 ++ .../test/https-first/browser_navigation.js | 97 ++ .../test/https-first/browser_schemeless.js | 191 +++ .../test/https-first/browser_slow_download.js | 158 ++ .../test/https-first/browser_superfluos_auth.js | 67 + .../test/https-first/browser_upgrade_onion.js | 60 + dom/security/test/https-first/download_page.html | 22 + dom/security/test/https-first/download_server.sjs | 16 + dom/security/test/https-first/file_bad_cert.sjs | 34 + .../https-first/file_beforeunload_permit_http.html | 9 + .../file_break_endless_upgrade_downgrade_loop.sjs | 61 + dom/security/test/https-first/file_data_uri.html | 16 + .../https-first/file_downgrade_500_responses.sjs | 70 + .../https-first/file_downgrade_bad_responses.sjs | 73 + .../file_downgrade_request_upgrade_request.sjs | 52 + .../https-first/file_downgrade_view_source.sjs | 30 + .../file_downgrade_with_different_path.sjs | 27 + .../test/https-first/file_download_attribute.html | 14 + .../test/https-first/file_download_attribute.sjs | 12 + .../test/https-first/file_form_submission.sjs | 84 ++ dom/security/test/https-first/file_fragment.html | 43 + .../file_httpsfirst_speculative_connect.html | 1 + .../https-first/file_httpsfirst_timeout_server.sjs | 13 + .../file_mixed_content_auto_upgrade.html | 12 + .../https-first/file_mixed_content_console.html | 13 + .../test/https-first/file_multiple_redirection.sjs | 87 ++ dom/security/test/https-first/file_navigation.html | 6 + dom/security/test/https-first/file_redirect.sjs | 58 + .../test/https-first/file_redirect_downgrade.sjs | 87 ++ .../test/https-first/file_referrer_policy.sjs | 102 ++ .../test/https-first/file_slow_download.html | 14 + .../test/https-first/file_slow_download.sjs | 26 + .../test/https-first/file_toplevel_cookies.sjs | 233 +++ .../test/https-first/file_upgrade_insecure.html | 72 + .../https-first/file_upgrade_insecure_server.sjs | 114 ++ dom/security/test/https-first/mochitest.toml | 56 + dom/security/test/https-first/pass.png | Bin 0 -> 1689 bytes dom/security/test/https-first/test.ogv | Bin 0 -> 2344665 bytes dom/security/test/https-first/test.wav | Bin 0 -> 353022 bytes dom/security/test/https-first/test_bad_cert.html | 67 + .../test_break_endless_upgrade_downgrade_loop.html | 80 + dom/security/test/https-first/test_data_uri.html | 51 + .../https-first/test_downgrade_500_responses.html | 63 + .../https-first/test_downgrade_bad_responses.html | 63 + .../test_downgrade_request_upgrade_request.html | 52 + .../test/https-first/test_form_submission.html | 122 ++ dom/security/test/https-first/test_fragment.html | 59 + .../https-first/test_multiple_redirection.html | 76 + .../test/https-first/test_redirect_downgrade.html | 59 + .../test/https-first/test_redirect_upgrade.html | 58 + .../test/https-first/test_referrer_policy.html | 237 +++ .../test/https-first/test_resource_upgrade.html | 115 ++ .../test/https-first/test_toplevel_cookies.html | 116 ++ dom/security/test/https-only/browser.toml | 62 + .../test/https-only/browser_background_redirect.js | 64 + dom/security/test/https-only/browser_bug1874801.js | 56 + .../test/https-only/browser_console_logging.js | 153 ++ .../https-only/browser_continue_button_delay.js | 59 + .../test/https-only/browser_cors_mixedcontent.js | 127 ++ dom/security/test/https-only/browser_hsts_host.js | 203 +++ .../test/https-only/browser_httpsonly_prefs.js | 118 ++ .../browser_httpsonly_speculative_connect.js | 71 + .../test/https-only/browser_iframe_test.js | 223 +++ dom/security/test/https-only/browser_navigation.js | 94 ++ .../test/https-only/browser_redirect_tainting.js | 39 + dom/security/test/https-only/browser_save_as.js | 187 +++ .../browser_triggering_principal_exemption.js | 72 + .../test/https-only/browser_upgrade_exceptions.js | 86 ++ .../test/https-only/browser_upgrade_exemption.js | 80 + .../test/https-only/browser_user_gesture.js | 55 + .../https-only/browser_websocket_exceptions.js | 68 + .../test/https-only/file_background_redirect.sjs | 32 + .../file_break_endless_upgrade_downgrade_loop.sjs | 67 + dom/security/test/https-only/file_bug1874801.html | 11 + dom/security/test/https-only/file_bug1874801.sjs | 17 + .../test/https-only/file_console_logging.html | 16 + .../test/https-only/file_cors_mixedcontent.html | 42 + dom/security/test/https-only/file_fragment.html | 47 + .../test/https-only/file_fragment_noscript.html | 9 + .../file_http_background_auth_request.sjs | 16 + .../https-only/file_http_background_request.sjs | 15 + .../file_httpsonly_speculative_connect.html | 1 + dom/security/test/https-only/file_iframe_test.sjs | 58 + .../test/https-only/file_insecure_reload.sjs | 27 + dom/security/test/https-only/file_redirect.sjs | 37 + .../test/https-only/file_redirect_tainting.sjs | 39 + .../test/https-only/file_redirect_to_insecure.sjs | 16 + dom/security/test/https-only/file_save_as.html | 10 + .../test/https-only/file_upgrade_insecure.html | 91 ++ .../https-only/file_upgrade_insecure_server.sjs | 112 ++ .../test/https-only/file_upgrade_insecure_wsh.py | 6 + .../test/https-only/file_user_gesture.html | 11 + .../test/https-only/file_websocket_exceptions.html | 9 + .../file_websocket_exceptions_iframe.html | 30 + dom/security/test/https-only/hsts_headers.sjs | 24 + dom/security/test/https-only/mochitest.toml | 65 + .../test_break_endless_upgrade_downgrade_loop.html | 89 ++ dom/security/test/https-only/test_fragment.html | 72 + .../test_http_background_auth_request.html | 113 ++ .../https-only/test_http_background_request.html | 125 ++ .../test/https-only/test_insecure_reload.html | 74 + .../test/https-only/test_redirect_upgrade.html | 58 + .../test/https-only/test_resource_upgrade.html | 122 ++ .../test/https-only/test_user_suggestion_box.html | 81 + .../auto_upgrading_identity.html | 11 + .../auto_upgrading_identity.png | Bin 0 -> 70 bytes dom/security/test/mixedcontentblocker/browser.toml | 35 + .../browser_auto_upgrading_identity.js | 58 + ...xedcontent_and_mixed_content_display_upgrade.js | 171 +++ .../browser_mixed_content_auth_download.js | 169 +++ ...r_mixed_content_auto_upgrade_display_console.js | 54 + .../browser_test_mixed_content_download.js | 341 +++++ .../test/mixedcontentblocker/download_page.html | 41 + .../test/mixedcontentblocker/download_server.sjs | 20 + .../file_auth_download_page.html | 22 + .../file_auth_download_server.sjs | 61 + .../test/mixedcontentblocker/file_bug1550792.html | 39 + .../test/mixedcontentblocker/file_bug1551886.html | 25 + .../file_bug803225_test_mailto.html | 13 + ...dcontent_and_mixed_content_display_upgrade.html | 14 + .../mixedcontentblocker/file_frameNavigation.html | 72 + .../file_frameNavigation_blankTarget.html | 33 + .../file_frameNavigation_grandchild.html | 55 + .../file_frameNavigation_innermost.html | 74 + .../file_frameNavigation_secure.html | 72 + .../file_frameNavigation_secure_grandchild.html | 56 + .../test/mixedcontentblocker/file_main.html | 336 +++++ .../mixedcontentblocker/file_main_bug803225.html | 175 +++ .../file_main_bug803225_websocket_wsh.py | 6 + ...mixed_content_auto_upgrade_display_console.html | 10 + .../test/mixedcontentblocker/file_redirect.html | 31 + .../mixedcontentblocker/file_redirect_handler.sjs | 34 + .../test/mixedcontentblocker/file_server.sjs | 131 ++ .../test/mixedcontentblocker/file_windowOpen.html | 9 + .../test/mixedcontentblocker/mochitest.toml | 66 + dom/security/test/mixedcontentblocker/pass.png | Bin 0 -> 1689 bytes dom/security/test/mixedcontentblocker/test.ogv | Bin 0 -> 2344665 bytes dom/security/test/mixedcontentblocker/test.wav | Bin 0 -> 353022 bytes .../test/mixedcontentblocker/test_bug1550792.html | 35 + .../test/mixedcontentblocker/test_bug1551886.html | 33 + .../test/mixedcontentblocker/test_bug803225.html | 157 ++ .../mixedcontentblocker/test_frameNavigation.html | 127 ++ .../test/mixedcontentblocker/test_main.html | 231 +++ .../test/mixedcontentblocker/test_redirect.html | 45 + .../test/mixedcontentblocker/test_windowOpen.html | 82 ++ dom/security/test/moz.build | 43 + dom/security/test/referrer-policy/browser.toml | 9 + .../referrer-policy/browser_fragment_navigation.js | 42 + ...rowser_referrer_disallow_cross_site_relaxing.js | 458 ++++++ .../referrer-policy/browser_referrer_telemetry.js | 126 ++ .../referrer-policy/file_fragment_navigation.sjs | 21 + .../referrer-policy/img_referrer_testserver.sjs | 337 +++++ dom/security/test/referrer-policy/mochitest.toml | 28 + .../test/referrer-policy/referrer_header.sjs | 6 + .../referrer_header_current_document_iframe.html | 12 + .../test/referrer-policy/referrer_helper.js | 129 ++ .../test/referrer-policy/referrer_page.sjs | 39 + .../test/referrer-policy/referrer_testserver.sjs | 704 +++++++++ .../test/referrer-policy/test_img_referrer.html | 190 +++ .../test_referrer_header_current_document.html | 35 + .../referrer-policy/test_referrer_redirect.html | 171 +++ dom/security/test/sec-fetch/browser.toml | 10 + .../test/sec-fetch/browser_external_loads.js | 176 +++ dom/security/test/sec-fetch/browser_navigation.js | 182 +++ dom/security/test/sec-fetch/file_dummy_link.html | 9 + .../test/sec-fetch/file_dummy_link_location.html | 9 + dom/security/test/sec-fetch/file_no_cache.sjs | 28 + dom/security/test/sec-fetch/file_redirect.sjs | 34 + .../test/sec-fetch/file_trustworthy_loopback.html | 11 + dom/security/test/sec-fetch/file_websocket_wsh.py | 6 + dom/security/test/sec-fetch/mochitest.toml | 29 + .../test_iframe_history_manipulation.html | 85 ++ .../sec-fetch/test_iframe_src_metaRedirect.html | 95 ++ .../sec-fetch/test_iframe_srcdoc_metaRedirect.html | 95 ++ .../test_iframe_window_open_metaRedirect.html | 98 ++ .../test/sec-fetch/test_trustworthy_loopback.html | 77 + dom/security/test/sec-fetch/test_websocket.html | 74 + dom/security/test/sri/file_bug_1271796.css | 2 + .../test/sri/iframe_script_crossdomain.html | 135 ++ .../test/sri/iframe_script_sameorigin.html | 249 ++++ .../test/sri/iframe_style_crossdomain.html | 117 ++ dom/security/test/sri/iframe_style_sameorigin.html | 164 +++ dom/security/test/sri/mochitest.toml | 56 + dom/security/test/sri/script.js | 1 + dom/security/test/sri/script.js^headers^ | 1 + dom/security/test/sri/script_301.js | 1 + dom/security/test/sri/script_301.js^headers^ | 2 + dom/security/test/sri/script_302.js | 1 + dom/security/test/sri/script_302.js^headers^ | 2 + dom/security/test/sri/script_401.js | 1 + dom/security/test/sri/script_401.js^headers^ | 2 + dom/security/test/sri/script_crossdomain1.js | 4 + .../test/sri/script_crossdomain1.js^headers^ | 1 + dom/security/test/sri/script_crossdomain2.js | 5 + dom/security/test/sri/script_crossdomain3.js | 1 + .../test/sri/script_crossdomain3.js^headers^ | 1 + dom/security/test/sri/script_crossdomain4.js | 1 + .../test/sri/script_crossdomain4.js^headers^ | 1 + dom/security/test/sri/script_crossdomain5.js | 1 + .../test/sri/script_crossdomain5.js^headers^ | 1 + dom/security/test/sri/style1.css | 3 + dom/security/test/sri/style1.css^headers^ | 1 + dom/security/test/sri/style2.css | 1 + dom/security/test/sri/style3.css | 3 + dom/security/test/sri/style4.css | 4 + dom/security/test/sri/style4.css^headers^ | 1 + dom/security/test/sri/style5.css | 4 + dom/security/test/sri/style6.css | 4 + dom/security/test/sri/style6.css^headers^ | 1 + dom/security/test/sri/style_301.css | 3 + dom/security/test/sri/style_301.css^headers^ | 2 + dom/security/test/sri/test_bug_1271796.html | 30 + dom/security/test/sri/test_bug_1364262.html | 34 + dom/security/test/sri/test_script_crossdomain.html | 15 + dom/security/test/sri/test_script_sameorigin.html | 15 + dom/security/test/sri/test_style_crossdomain.html | 15 + dom/security/test/sri/test_style_sameorigin.html | 15 + dom/security/test/unit/test_csp_reports.js | 299 ++++ .../test_csp_upgrade_insecure_request_header.js | 103 ++ .../unit/test_deserialization_format_before_100.js | 244 +++ .../test_https_only_https_first_default_port.js | 111 ++ .../test/unit/test_https_only_https_first_prefs.js | 361 +++++ .../unit/test_isOriginPotentiallyTrustworthy.js | 53 + dom/security/test/unit/xpcshell.toml | 16 + 796 files changed, 46935 insertions(+) create mode 100644 dom/security/test/cors/browser.toml create mode 100644 dom/security/test/cors/browser_CORS-console-warnings.js create mode 100644 dom/security/test/cors/bug1456721.sjs create mode 100644 dom/security/test/cors/file_CrossSiteXHR_cache_server.sjs create mode 100644 dom/security/test/cors/file_CrossSiteXHR_inner.html create mode 100644 dom/security/test/cors/file_CrossSiteXHR_inner.jar create mode 100644 dom/security/test/cors/file_CrossSiteXHR_inner_data.sjs create mode 100644 dom/security/test/cors/file_CrossSiteXHR_server.sjs create mode 100644 dom/security/test/cors/file_bug1456721.html create mode 100644 dom/security/test/cors/file_cors_logging_test.html create mode 100644 dom/security/test/cors/file_cors_logging_test.html.css create mode 100644 dom/security/test/cors/mochitest.toml create mode 100644 dom/security/test/cors/test_CrossSiteXHR.html create mode 100644 dom/security/test/cors/test_CrossSiteXHR_cache.html create mode 100644 dom/security/test/cors/test_CrossSiteXHR_origin.html create mode 100644 dom/security/test/crashtests/1577572.html create mode 100644 dom/security/test/crashtests/1583044.html create mode 100644 dom/security/test/crashtests/crashtests.list create mode 100644 dom/security/test/csp/Ahem.ttf create mode 100644 dom/security/test/csp/File create mode 100644 dom/security/test/csp/browser.toml create mode 100644 dom/security/test/csp/browser_manifest-src-override-default-src.js create mode 100644 dom/security/test/csp/browser_pdfjs_not_subject_to_csp.js create mode 100644 dom/security/test/csp/browser_test_bookmarklets.js create mode 100644 dom/security/test/csp/browser_test_uir_optional_clicks.js create mode 100644 dom/security/test/csp/browser_test_web_manifest.js create mode 100644 dom/security/test/csp/browser_test_web_manifest_mixed_content.js create mode 100644 dom/security/test/csp/dummy.pdf create mode 100644 dom/security/test/csp/file_CSP.css create mode 100644 dom/security/test/csp/file_CSP.sjs create mode 100644 dom/security/test/csp/file_allow_https_schemes.html create mode 100644 dom/security/test/csp/file_base_uri_server.sjs create mode 100644 dom/security/test/csp/file_blob_data_schemes.html create mode 100644 dom/security/test/csp/file_blob_top_nav_block_modals.html create mode 100644 dom/security/test/csp/file_blob_top_nav_block_modals.html^headers^ create mode 100644 dom/security/test/csp/file_blob_uri_blocks_modals.html create mode 100644 dom/security/test/csp/file_blob_uri_blocks_modals.html^headers^ create mode 100644 dom/security/test/csp/file_block_all_mcb.sjs create mode 100644 dom/security/test/csp/file_block_all_mixed_content_frame_navigation1.html create mode 100644 dom/security/test/csp/file_block_all_mixed_content_frame_navigation2.html create mode 100644 dom/security/test/csp/file_blocked_uri_in_violation_event_after_redirects.html create mode 100644 dom/security/test/csp/file_blocked_uri_in_violation_event_after_redirects.sjs create mode 100644 dom/security/test/csp/file_blocked_uri_redirect_frame_src.html create mode 100644 dom/security/test/csp/file_blocked_uri_redirect_frame_src.html^headers^ create mode 100644 dom/security/test/csp/file_blocked_uri_redirect_frame_src_server.sjs create mode 100644 dom/security/test/csp/file_bug1229639.html create mode 100644 dom/security/test/csp/file_bug1229639.html^headers^ create mode 100644 dom/security/test/csp/file_bug1312272.html create mode 100644 dom/security/test/csp/file_bug1312272.html^headers^ create mode 100644 dom/security/test/csp/file_bug1312272.js create mode 100644 dom/security/test/csp/file_bug1452037.html create mode 100644 dom/security/test/csp/file_bug1505412.sjs create mode 100644 dom/security/test/csp/file_bug1505412_frame.html create mode 100644 dom/security/test/csp/file_bug1505412_frame.html^headers^ create mode 100644 dom/security/test/csp/file_bug1505412_reporter.sjs create mode 100644 dom/security/test/csp/file_bug1738418_child.html create mode 100644 dom/security/test/csp/file_bug1738418_parent.html create mode 100644 dom/security/test/csp/file_bug1738418_parent.html^headers^ create mode 100644 dom/security/test/csp/file_bug1764343.html create mode 100644 dom/security/test/csp/file_bug1777572.html create mode 100644 dom/security/test/csp/file_bug663567.xsl create mode 100644 dom/security/test/csp/file_bug663567_allows.xml create mode 100644 dom/security/test/csp/file_bug663567_allows.xml^headers^ create mode 100644 dom/security/test/csp/file_bug663567_blocks.xml create mode 100644 dom/security/test/csp/file_bug663567_blocks.xml^headers^ create mode 100644 dom/security/test/csp/file_bug802872.html create mode 100644 dom/security/test/csp/file_bug802872.html^headers^ create mode 100644 dom/security/test/csp/file_bug802872.js create mode 100644 dom/security/test/csp/file_bug802872.sjs create mode 100644 dom/security/test/csp/file_bug836922_npolicies.html create mode 100644 dom/security/test/csp/file_bug836922_npolicies.html^headers^ create mode 100644 dom/security/test/csp/file_bug836922_npolicies_ro_violation.sjs create mode 100644 dom/security/test/csp/file_bug836922_npolicies_violation.sjs create mode 100644 dom/security/test/csp/file_bug885433_allows.html create mode 100644 dom/security/test/csp/file_bug885433_allows.html^headers^ create mode 100644 dom/security/test/csp/file_bug885433_blocks.html create mode 100644 dom/security/test/csp/file_bug885433_blocks.html^headers^ create mode 100644 dom/security/test/csp/file_bug886164.html create mode 100644 dom/security/test/csp/file_bug886164.html^headers^ create mode 100644 dom/security/test/csp/file_bug886164_2.html create mode 100644 dom/security/test/csp/file_bug886164_2.html^headers^ create mode 100644 dom/security/test/csp/file_bug886164_3.html create mode 100644 dom/security/test/csp/file_bug886164_3.html^headers^ create mode 100644 dom/security/test/csp/file_bug886164_4.html create mode 100644 dom/security/test/csp/file_bug886164_4.html^headers^ create mode 100644 dom/security/test/csp/file_bug886164_5.html create mode 100644 dom/security/test/csp/file_bug886164_5.html^headers^ create mode 100644 dom/security/test/csp/file_bug886164_6.html create mode 100644 dom/security/test/csp/file_bug886164_6.html^headers^ create mode 100644 dom/security/test/csp/file_bug888172.html create mode 100644 dom/security/test/csp/file_bug888172.sjs create mode 100644 dom/security/test/csp/file_bug909029_none.html create mode 100644 dom/security/test/csp/file_bug909029_none.html^headers^ create mode 100644 dom/security/test/csp/file_bug909029_star.html create mode 100644 dom/security/test/csp/file_bug909029_star.html^headers^ create mode 100644 dom/security/test/csp/file_bug910139.sjs create mode 100644 dom/security/test/csp/file_bug910139.xml create mode 100644 dom/security/test/csp/file_bug910139.xsl create mode 100644 dom/security/test/csp/file_bug941404.html create mode 100644 dom/security/test/csp/file_bug941404_xhr.html create mode 100644 dom/security/test/csp/file_bug941404_xhr.html^headers^ create mode 100644 dom/security/test/csp/file_child-src_iframe.html create mode 100644 dom/security/test/csp/file_child-src_inner_frame.html create mode 100644 dom/security/test/csp/file_child-src_service_worker.html create mode 100644 dom/security/test/csp/file_child-src_service_worker.js create mode 100644 dom/security/test/csp/file_child-src_shared_worker-redirect.html create mode 100644 dom/security/test/csp/file_child-src_shared_worker.html create mode 100644 dom/security/test/csp/file_child-src_shared_worker.js create mode 100644 dom/security/test/csp/file_child-src_shared_worker_data.html create mode 100644 dom/security/test/csp/file_child-src_worker-redirect.html create mode 100644 dom/security/test/csp/file_child-src_worker.html create mode 100644 dom/security/test/csp/file_child-src_worker.js create mode 100644 dom/security/test/csp/file_child-src_worker_data.html create mode 100644 dom/security/test/csp/file_connect-src-fetch.html create mode 100644 dom/security/test/csp/file_connect-src.html create mode 100644 dom/security/test/csp/file_csp_frame_ancestors_about_blank.html create mode 100644 dom/security/test/csp/file_csp_frame_ancestors_about_blank.html^headers^ create mode 100644 dom/security/test/csp/file_csp_meta_uir.html create mode 100644 dom/security/test/csp/file_data-uri_blocked.html create mode 100644 dom/security/test/csp/file_data-uri_blocked.html^headers^ create mode 100644 dom/security/test/csp/file_data_csp_inheritance.html create mode 100644 dom/security/test/csp/file_data_csp_merge.html create mode 100644 dom/security/test/csp/file_data_doc_ignore_meta_csp.html create mode 100644 dom/security/test/csp/file_doccomment_meta.html create mode 100644 dom/security/test/csp/file_docwrite_meta.css create mode 100644 dom/security/test/csp/file_docwrite_meta.html create mode 100644 dom/security/test/csp/file_docwrite_meta.js create mode 100644 dom/security/test/csp/file_dual_header_testserver.sjs create mode 100644 dom/security/test/csp/file_dummy_pixel.png create mode 100644 dom/security/test/csp/file_empty_directive.html create mode 100644 dom/security/test/csp/file_empty_directive.html^headers^ create mode 100644 dom/security/test/csp/file_evalscript_main.html create mode 100644 dom/security/test/csp/file_evalscript_main.html^headers^ create mode 100644 dom/security/test/csp/file_evalscript_main.js create mode 100644 dom/security/test/csp/file_evalscript_main_allowed.html create mode 100644 dom/security/test/csp/file_evalscript_main_allowed.html^headers^ create mode 100644 dom/security/test/csp/file_evalscript_main_allowed.js create mode 100644 dom/security/test/csp/file_fontloader.sjs create mode 100644 dom/security/test/csp/file_fontloader.woff create mode 100644 dom/security/test/csp/file_form-action.html create mode 100644 dom/security/test/csp/file_form_action_server.sjs create mode 100644 dom/security/test/csp/file_frame_ancestors_ro.html create mode 100644 dom/security/test/csp/file_frame_ancestors_ro.html^headers^ create mode 100644 dom/security/test/csp/file_frame_src.js create mode 100644 dom/security/test/csp/file_frame_src_child_governs.html create mode 100644 dom/security/test/csp/file_frame_src_frame_governs.html create mode 100644 dom/security/test/csp/file_frame_src_inner.html create mode 100644 dom/security/test/csp/file_frameancestors.sjs create mode 100644 dom/security/test/csp/file_frameancestors_main.html create mode 100644 dom/security/test/csp/file_frameancestors_main.js create mode 100644 dom/security/test/csp/file_frameancestors_userpass.html create mode 100644 dom/security/test/csp/file_frameancestors_userpass_frame_a.html create mode 100644 dom/security/test/csp/file_frameancestors_userpass_frame_b.html create mode 100644 dom/security/test/csp/file_frameancestors_userpass_frame_c.html create mode 100644 dom/security/test/csp/file_frameancestors_userpass_frame_c.html^headers^ create mode 100644 dom/security/test/csp/file_frameancestors_userpass_frame_d.html create mode 100644 dom/security/test/csp/file_frameancestors_userpass_frame_d.html^headers^ create mode 100644 dom/security/test/csp/file_hash_source.html create mode 100644 dom/security/test/csp/file_hash_source.html^headers^ create mode 100644 dom/security/test/csp/file_iframe_parent_location_js.html create mode 100644 dom/security/test/csp/file_iframe_sandbox_document_write.html create mode 100644 dom/security/test/csp/file_iframe_sandbox_srcdoc.html create mode 100644 dom/security/test/csp/file_iframe_sandbox_srcdoc.html^headers^ create mode 100644 dom/security/test/csp/file_iframe_srcdoc.sjs create mode 100644 dom/security/test/csp/file_ignore_unsafe_inline.html create mode 100644 dom/security/test/csp/file_ignore_unsafe_inline_multiple_policies_server.sjs create mode 100644 dom/security/test/csp/file_ignore_xfo.html create mode 100644 dom/security/test/csp/file_ignore_xfo.html^headers^ create mode 100644 dom/security/test/csp/file_image_document_pixel.png create mode 100644 dom/security/test/csp/file_image_document_pixel.png^headers^ create mode 100644 dom/security/test/csp/file_image_nonce.html create mode 100644 dom/security/test/csp/file_image_nonce.html^headers^ create mode 100644 dom/security/test/csp/file_independent_iframe_csp.html create mode 100644 dom/security/test/csp/file_inlinescript.html create mode 100644 dom/security/test/csp/file_inlinestyle_main.html create mode 100644 dom/security/test/csp/file_inlinestyle_main.html^headers^ create mode 100644 dom/security/test/csp/file_inlinestyle_main_allowed.html create mode 100644 dom/security/test/csp/file_inlinestyle_main_allowed.html^headers^ create mode 100644 dom/security/test/csp/file_invalid_source_expression.html create mode 100644 dom/security/test/csp/file_leading_wildcard.html create mode 100644 dom/security/test/csp/file_link_rel_preload.html create mode 100644 dom/security/test/csp/file_main.html create mode 100644 dom/security/test/csp/file_main.html^headers^ create mode 100644 dom/security/test/csp/file_main.js create mode 100644 dom/security/test/csp/file_meta_element.html create mode 100644 dom/security/test/csp/file_meta_header_dual.sjs create mode 100644 dom/security/test/csp/file_meta_whitespace_skipping.html create mode 100644 dom/security/test/csp/file_multi_policy_injection_bypass.html create mode 100644 dom/security/test/csp/file_multi_policy_injection_bypass.html^headers^ create mode 100644 dom/security/test/csp/file_multi_policy_injection_bypass_2.html create mode 100644 dom/security/test/csp/file_multi_policy_injection_bypass_2.html^headers^ create mode 100644 dom/security/test/csp/file_multipart_testserver.sjs create mode 100644 dom/security/test/csp/file_no_log_ignore_xfo.html create mode 100644 dom/security/test/csp/file_no_log_ignore_xfo.html^headers^ create mode 100644 dom/security/test/csp/file_nonce_redirector.sjs create mode 100644 dom/security/test/csp/file_nonce_redirects.html create mode 100644 dom/security/test/csp/file_nonce_snapshot.sjs create mode 100644 dom/security/test/csp/file_nonce_source.html create mode 100644 dom/security/test/csp/file_nonce_source.html^headers^ create mode 100644 dom/security/test/csp/file_null_baseuri.html create mode 100644 dom/security/test/csp/file_object_inherit.html create mode 100644 dom/security/test/csp/file_parent_location_js.html create mode 100644 dom/security/test/csp/file_path_matching.html create mode 100644 dom/security/test/csp/file_path_matching.js create mode 100644 dom/security/test/csp/file_path_matching_incl_query.html create mode 100644 dom/security/test/csp/file_path_matching_redirect.html create mode 100644 dom/security/test/csp/file_path_matching_redirect_server.sjs create mode 100644 dom/security/test/csp/file_pdfjs_not_subject_to_csp.html create mode 100644 dom/security/test/csp/file_ping.html create mode 100644 dom/security/test/csp/file_policyuri_regression_from_multipolicy.html create mode 100644 dom/security/test/csp/file_policyuri_regression_from_multipolicy.html^headers^ create mode 100644 dom/security/test/csp/file_policyuri_regression_from_multipolicy_policy create mode 100644 dom/security/test/csp/file_punycode_host_src.js create mode 100644 dom/security/test/csp/file_punycode_host_src.sjs create mode 100644 dom/security/test/csp/file_redirect_content.sjs create mode 100644 dom/security/test/csp/file_redirect_report.sjs create mode 100644 dom/security/test/csp/file_redirect_worker.sjs create mode 100644 dom/security/test/csp/file_redirects_main.html create mode 100644 dom/security/test/csp/file_redirects_page.sjs create mode 100644 dom/security/test/csp/file_redirects_resource.sjs create mode 100644 dom/security/test/csp/file_report.html create mode 100644 dom/security/test/csp/file_report_chromescript.js create mode 100644 dom/security/test/csp/file_report_font_cache-1.html create mode 100644 dom/security/test/csp/file_report_font_cache-2.html create mode 100644 dom/security/test/csp/file_report_font_cache-2.html^headers^ create mode 100644 dom/security/test/csp/file_report_for_import.css create mode 100644 dom/security/test/csp/file_report_for_import.html create mode 100644 dom/security/test/csp/file_report_for_import_server.sjs create mode 100644 dom/security/test/csp/file_report_uri_missing_in_report_only_header.html create mode 100644 dom/security/test/csp/file_report_uri_missing_in_report_only_header.html^headers^ create mode 100644 dom/security/test/csp/file_ro_ignore_xfo.html create mode 100644 dom/security/test/csp/file_ro_ignore_xfo.html^headers^ create mode 100644 dom/security/test/csp/file_sandbox_1.html create mode 100644 dom/security/test/csp/file_sandbox_10.html create mode 100644 dom/security/test/csp/file_sandbox_11.html create mode 100644 dom/security/test/csp/file_sandbox_12.html create mode 100644 dom/security/test/csp/file_sandbox_13.html create mode 100644 dom/security/test/csp/file_sandbox_2.html create mode 100644 dom/security/test/csp/file_sandbox_3.html create mode 100644 dom/security/test/csp/file_sandbox_4.html create mode 100644 dom/security/test/csp/file_sandbox_5.html create mode 100644 dom/security/test/csp/file_sandbox_6.html create mode 100644 dom/security/test/csp/file_sandbox_7.html create mode 100644 dom/security/test/csp/file_sandbox_8.html create mode 100644 dom/security/test/csp/file_sandbox_9.html create mode 100644 dom/security/test/csp/file_sandbox_allow_scripts.html create mode 100644 dom/security/test/csp/file_sandbox_allow_scripts.html^headers^ create mode 100644 dom/security/test/csp/file_sandbox_fail.js create mode 100644 dom/security/test/csp/file_sandbox_pass.js create mode 100644 dom/security/test/csp/file_scheme_relative_sources.js create mode 100644 dom/security/test/csp/file_scheme_relative_sources.sjs create mode 100644 dom/security/test/csp/file_script_template.html create mode 100644 dom/security/test/csp/file_script_template.js create mode 100644 dom/security/test/csp/file_self_none_as_hostname_confusion.html create mode 100644 dom/security/test/csp/file_self_none_as_hostname_confusion.html^headers^ create mode 100644 dom/security/test/csp/file_sendbeacon.html create mode 100644 dom/security/test/csp/file_service_worker.html create mode 100644 dom/security/test/csp/file_service_worker.js create mode 100644 dom/security/test/csp/file_spawn_service_worker.js create mode 100644 dom/security/test/csp/file_spawn_shared_worker.js create mode 100644 dom/security/test/csp/file_spawn_worker.js create mode 100644 dom/security/test/csp/file_strict_dynamic.js create mode 100644 dom/security/test/csp/file_strict_dynamic_default_src.html create mode 100644 dom/security/test/csp/file_strict_dynamic_default_src.js create mode 100644 dom/security/test/csp/file_strict_dynamic_js_url.html create mode 100644 dom/security/test/csp/file_strict_dynamic_non_parser_inserted.html create mode 100644 dom/security/test/csp/file_strict_dynamic_non_parser_inserted_inline.html create mode 100644 dom/security/test/csp/file_strict_dynamic_parser_inserted_doc_write.html create mode 100644 dom/security/test/csp/file_strict_dynamic_parser_inserted_doc_write_correct_nonce.html create mode 100644 dom/security/test/csp/file_strict_dynamic_script_events.html create mode 100644 dom/security/test/csp/file_strict_dynamic_script_events_marquee.html create mode 100644 dom/security/test/csp/file_strict_dynamic_script_extern.html create mode 100644 dom/security/test/csp/file_strict_dynamic_script_inline.html create mode 100644 dom/security/test/csp/file_strict_dynamic_unsafe_eval.html create mode 100644 dom/security/test/csp/file_subframe_run_js_if_allowed.html create mode 100644 dom/security/test/csp/file_subframe_run_js_if_allowed.html^headers^ create mode 100644 dom/security/test/csp/file_svg_inline_style_base.html create mode 100644 dom/security/test/csp/file_svg_inline_style_csp.html create mode 100644 dom/security/test/csp/file_svg_inline_style_server.sjs create mode 100644 dom/security/test/csp/file_svg_srcset_inline_style_base.html create mode 100644 dom/security/test/csp/file_svg_srcset_inline_style_csp.html create mode 100644 dom/security/test/csp/file_test_browser_bookmarklets.html create mode 100644 dom/security/test/csp/file_test_browser_bookmarklets.html^headers^ create mode 100644 dom/security/test/csp/file_testserver.sjs create mode 100644 dom/security/test/csp/file_uir_top_nav.html create mode 100644 dom/security/test/csp/file_uir_top_nav_dummy.html create mode 100644 dom/security/test/csp/file_upgrade_insecure.html create mode 100644 dom/security/test/csp/file_upgrade_insecure_cors.html create mode 100644 dom/security/test/csp/file_upgrade_insecure_cors_server.sjs create mode 100644 dom/security/test/csp/file_upgrade_insecure_docwrite_iframe.sjs create mode 100644 dom/security/test/csp/file_upgrade_insecure_loopback.html create mode 100644 dom/security/test/csp/file_upgrade_insecure_loopback_form.html create mode 100644 dom/security/test/csp/file_upgrade_insecure_loopback_server.sjs create mode 100644 dom/security/test/csp/file_upgrade_insecure_meta.html create mode 100644 dom/security/test/csp/file_upgrade_insecure_navigation.sjs create mode 100644 dom/security/test/csp/file_upgrade_insecure_navigation_redirect.sjs create mode 100644 dom/security/test/csp/file_upgrade_insecure_navigation_redirect_cross_origin.html create mode 100644 dom/security/test/csp/file_upgrade_insecure_navigation_redirect_same_origin.html create mode 100644 dom/security/test/csp/file_upgrade_insecure_report_only.html create mode 100644 dom/security/test/csp/file_upgrade_insecure_report_only_server.sjs create mode 100644 dom/security/test/csp/file_upgrade_insecure_reporting.html create mode 100644 dom/security/test/csp/file_upgrade_insecure_reporting_server.sjs create mode 100644 dom/security/test/csp/file_upgrade_insecure_server.sjs create mode 100644 dom/security/test/csp/file_upgrade_insecure_wsh.py create mode 100644 dom/security/test/csp/file_web_manifest.html create mode 100644 dom/security/test/csp/file_web_manifest.json create mode 100644 dom/security/test/csp/file_web_manifest.json^headers^ create mode 100644 dom/security/test/csp/file_web_manifest_https.html create mode 100644 dom/security/test/csp/file_web_manifest_https.json create mode 100644 dom/security/test/csp/file_web_manifest_mixed_content.html create mode 100644 dom/security/test/csp/file_web_manifest_remote.html create mode 100644 dom/security/test/csp/file_websocket_csp_upgrade.html create mode 100644 dom/security/test/csp/file_websocket_explicit.html create mode 100644 dom/security/test/csp/file_websocket_self.html create mode 100644 dom/security/test/csp/file_websocket_self_wsh.py create mode 100644 dom/security/test/csp/file_win_open_blocked.html create mode 100644 dom/security/test/csp/file_windowwatcher_frameA.html create mode 100644 dom/security/test/csp/file_windowwatcher_subframeB.html create mode 100644 dom/security/test/csp/file_windowwatcher_subframeC.html create mode 100644 dom/security/test/csp/file_windowwatcher_subframeD.html create mode 100644 dom/security/test/csp/file_windowwatcher_win_open.html create mode 100644 dom/security/test/csp/file_worker_src.js create mode 100644 dom/security/test/csp/file_worker_src_child_governs.html create mode 100644 dom/security/test/csp/file_worker_src_script_governs.html create mode 100644 dom/security/test/csp/file_worker_src_worker_governs.html create mode 100644 dom/security/test/csp/file_xslt_inherits_csp.xml create mode 100644 dom/security/test/csp/file_xslt_inherits_csp.xml^headers^ create mode 100644 dom/security/test/csp/file_xslt_inherits_csp.xsl create mode 100644 dom/security/test/csp/main_csp_worker.html create mode 100644 dom/security/test/csp/main_csp_worker.html^headers^ create mode 100644 dom/security/test/csp/mochitest.toml create mode 100644 dom/security/test/csp/referrerdirective.sjs create mode 100644 dom/security/test/csp/test_301_redirect.html create mode 100644 dom/security/test/csp/test_302_redirect.html create mode 100644 dom/security/test/csp/test_303_redirect.html create mode 100644 dom/security/test/csp/test_307_redirect.html create mode 100644 dom/security/test/csp/test_CSP.html create mode 100644 dom/security/test/csp/test_allow_https_schemes.html create mode 100644 dom/security/test/csp/test_base-uri.html create mode 100644 dom/security/test/csp/test_blob_data_schemes.html create mode 100644 dom/security/test/csp/test_blob_uri_blocks_modals.html create mode 100644 dom/security/test/csp/test_block_all_mixed_content.html create mode 100644 dom/security/test/csp/test_block_all_mixed_content_frame_navigation.html create mode 100644 dom/security/test/csp/test_blocked_uri_in_reports.html create mode 100644 dom/security/test/csp/test_blocked_uri_in_violation_event_after_redirects.html create mode 100644 dom/security/test/csp/test_blocked_uri_redirect_frame_src.html create mode 100644 dom/security/test/csp/test_bug1229639.html create mode 100644 dom/security/test/csp/test_bug1242019.html create mode 100644 dom/security/test/csp/test_bug1312272.html create mode 100644 dom/security/test/csp/test_bug1388015.html create mode 100644 dom/security/test/csp/test_bug1452037.html create mode 100644 dom/security/test/csp/test_bug1505412.html create mode 100644 dom/security/test/csp/test_bug1579094.html create mode 100644 dom/security/test/csp/test_bug1738418.html create mode 100644 dom/security/test/csp/test_bug1764343.html create mode 100644 dom/security/test/csp/test_bug1777572.html create mode 100644 dom/security/test/csp/test_bug663567.html create mode 100644 dom/security/test/csp/test_bug802872.html create mode 100644 dom/security/test/csp/test_bug836922_npolicies.html create mode 100644 dom/security/test/csp/test_bug885433.html create mode 100644 dom/security/test/csp/test_bug886164.html create mode 100644 dom/security/test/csp/test_bug888172.html create mode 100644 dom/security/test/csp/test_bug909029.html create mode 100644 dom/security/test/csp/test_bug910139.html create mode 100644 dom/security/test/csp/test_bug941404.html create mode 100644 dom/security/test/csp/test_child-src_iframe.html create mode 100644 dom/security/test/csp/test_child-src_worker-redirect.html create mode 100644 dom/security/test/csp/test_child-src_worker.html create mode 100644 dom/security/test/csp/test_child-src_worker_data.html create mode 100644 dom/security/test/csp/test_connect-src.html create mode 100644 dom/security/test/csp/test_csp_frame_ancestors_about_blank.html create mode 100644 dom/security/test/csp/test_csp_style_src_empty_hash.html create mode 100644 dom/security/test/csp/test_csp_worker_inheritance.html create mode 100644 dom/security/test/csp/test_data_csp_inheritance.html create mode 100644 dom/security/test/csp/test_data_csp_merge.html create mode 100644 dom/security/test/csp/test_data_doc_ignore_meta_csp.html create mode 100644 dom/security/test/csp/test_docwrite_meta.html create mode 100644 dom/security/test/csp/test_dual_header.html create mode 100644 dom/security/test/csp/test_empty_directive.html create mode 100644 dom/security/test/csp/test_evalscript.html create mode 100644 dom/security/test/csp/test_evalscript_allowed_by_strict_dynamic.html create mode 100644 dom/security/test/csp/test_evalscript_blocked_by_strict_dynamic.html create mode 100644 dom/security/test/csp/test_fontloader.html create mode 100644 dom/security/test/csp/test_form-action.html create mode 100644 dom/security/test/csp/test_form_action_blocks_url.html create mode 100644 dom/security/test/csp/test_frame_ancestors_ro.html create mode 100644 dom/security/test/csp/test_frame_src.html create mode 100644 dom/security/test/csp/test_frameancestors.html create mode 100644 dom/security/test/csp/test_frameancestors_userpass.html create mode 100644 dom/security/test/csp/test_hash_source.html create mode 100644 dom/security/test/csp/test_iframe_sandbox.html create mode 100644 dom/security/test/csp/test_iframe_sandbox_srcdoc.html create mode 100644 dom/security/test/csp/test_iframe_sandbox_top_1.html create mode 100644 dom/security/test/csp/test_iframe_sandbox_top_1.html^headers^ create mode 100644 dom/security/test/csp/test_iframe_srcdoc.html create mode 100644 dom/security/test/csp/test_ignore_unsafe_inline.html create mode 100644 dom/security/test/csp/test_ignore_xfo.html create mode 100644 dom/security/test/csp/test_image_document.html create mode 100644 dom/security/test/csp/test_image_nonce.html create mode 100644 dom/security/test/csp/test_independent_iframe_csp.html create mode 100644 dom/security/test/csp/test_inlinescript.html create mode 100644 dom/security/test/csp/test_inlinestyle.html create mode 100644 dom/security/test/csp/test_invalid_source_expression.html create mode 100644 dom/security/test/csp/test_leading_wildcard.html create mode 100644 dom/security/test/csp/test_link_rel_preload.html create mode 100644 dom/security/test/csp/test_meta_csp_self.html create mode 100644 dom/security/test/csp/test_meta_element.html create mode 100644 dom/security/test/csp/test_meta_header_dual.html create mode 100644 dom/security/test/csp/test_meta_whitespace_skipping.html create mode 100644 dom/security/test/csp/test_multi_policy_injection_bypass.html create mode 100644 dom/security/test/csp/test_multipartchannel.html create mode 100644 dom/security/test/csp/test_nonce_redirects.html create mode 100644 dom/security/test/csp/test_nonce_snapshot.html create mode 100644 dom/security/test/csp/test_nonce_source.html create mode 100644 dom/security/test/csp/test_null_baseuri.html create mode 100644 dom/security/test/csp/test_object_inherit.html create mode 100644 dom/security/test/csp/test_parent_location_js.html create mode 100644 dom/security/test/csp/test_path_matching.html create mode 100644 dom/security/test/csp/test_path_matching_redirect.html create mode 100644 dom/security/test/csp/test_ping.html create mode 100644 dom/security/test/csp/test_policyuri_regression_from_multipolicy.html create mode 100644 dom/security/test/csp/test_punycode_host_src.html create mode 100644 dom/security/test/csp/test_redirects.html create mode 100644 dom/security/test/csp/test_report.html create mode 100644 dom/security/test/csp/test_report_font_cache.html create mode 100644 dom/security/test/csp/test_report_for_import.html create mode 100644 dom/security/test/csp/test_report_uri_missing_in_report_only_header.html create mode 100644 dom/security/test/csp/test_sandbox.html create mode 100644 dom/security/test/csp/test_sandbox_allow_scripts.html create mode 100644 dom/security/test/csp/test_scheme_relative_sources.html create mode 100644 dom/security/test/csp/test_script_template.html create mode 100644 dom/security/test/csp/test_security_policy_violation_event.html create mode 100644 dom/security/test/csp/test_self_none_as_hostname_confusion.html create mode 100644 dom/security/test/csp/test_sendbeacon.html create mode 100644 dom/security/test/csp/test_service_worker.html create mode 100644 dom/security/test/csp/test_strict_dynamic.html create mode 100644 dom/security/test/csp/test_strict_dynamic_default_src.html create mode 100644 dom/security/test/csp/test_strict_dynamic_parser_inserted.html create mode 100644 dom/security/test/csp/test_subframe_run_js_if_allowed.html create mode 100644 dom/security/test/csp/test_svg_inline_style.html create mode 100644 dom/security/test/csp/test_uir_top_nav.html create mode 100644 dom/security/test/csp/test_uir_windowwatcher.html create mode 100644 dom/security/test/csp/test_upgrade_insecure.html create mode 100644 dom/security/test/csp/test_upgrade_insecure_cors.html create mode 100644 dom/security/test/csp/test_upgrade_insecure_docwrite_iframe.html create mode 100644 dom/security/test/csp/test_upgrade_insecure_loopback.html create mode 100644 dom/security/test/csp/test_upgrade_insecure_navigation.html create mode 100644 dom/security/test/csp/test_upgrade_insecure_navigation_redirect.html create mode 100644 dom/security/test/csp/test_upgrade_insecure_report_only.html create mode 100644 dom/security/test/csp/test_upgrade_insecure_reporting.html create mode 100644 dom/security/test/csp/test_websocket_localhost.html create mode 100644 dom/security/test/csp/test_websocket_self.html create mode 100644 dom/security/test/csp/test_win_open_blocked.html create mode 100644 dom/security/test/csp/test_worker_src.html create mode 100644 dom/security/test/csp/test_xslt_inherits_csp.html create mode 100644 dom/security/test/csp/worker.sjs create mode 100644 dom/security/test/csp/worker_helper.js create mode 100644 dom/security/test/general/browser.toml create mode 100644 dom/security/test/general/browser_file_nonscript.js create mode 100644 dom/security/test/general/browser_restrict_privileged_about_script.js create mode 100644 dom/security/test/general/browser_same_site_cookies_bug1748693.js create mode 100644 dom/security/test/general/browser_test_assert_systemprincipal_documents.js create mode 100644 dom/security/test/general/browser_test_data_download.js create mode 100644 dom/security/test/general/browser_test_data_text_csv.js create mode 100644 dom/security/test/general/browser_test_framing_error_pages.js create mode 100644 dom/security/test/general/browser_test_gpc_privateBrowsingMode.js create mode 100644 dom/security/test/general/browser_test_referrer_loadInOtherProcess.js create mode 100644 dom/security/test/general/browser_test_report_blocking.js create mode 100644 dom/security/test/general/browser_test_toplevel_data_navigations.js create mode 100644 dom/security/test/general/browser_test_view_image_data_navigation.js create mode 100644 dom/security/test/general/browser_test_xfo_embed_object.js create mode 100644 dom/security/test/general/bug1277803.html create mode 100644 dom/security/test/general/chrome.toml create mode 100644 dom/security/test/general/closeWindow.sjs create mode 100644 dom/security/test/general/favicon_bug1277803.ico create mode 100644 dom/security/test/general/file_1767581.js create mode 100644 dom/security/test/general/file_about_child.html create mode 100644 dom/security/test/general/file_assert_systemprincipal_documents.html create mode 100644 dom/security/test/general/file_assert_systemprincipal_documents_iframe.html create mode 100644 dom/security/test/general/file_block_script_wrong_mime_server.sjs create mode 100644 dom/security/test/general/file_block_subresource_redir_to_data.sjs create mode 100644 dom/security/test/general/file_block_toplevel_data_navigation.html create mode 100644 dom/security/test/general/file_block_toplevel_data_navigation2.html create mode 100644 dom/security/test/general/file_block_toplevel_data_navigation3.html create mode 100644 dom/security/test/general/file_block_toplevel_data_redirect.sjs create mode 100644 dom/security/test/general/file_cache_splitting_isloaded.sjs create mode 100644 dom/security/test/general/file_cache_splitting_server.sjs create mode 100644 dom/security/test/general/file_cache_splitting_window.html create mode 100644 dom/security/test/general/file_contentpolicytype_targeted_link_iframe.sjs create mode 100644 dom/security/test/general/file_data_download.html create mode 100644 dom/security/test/general/file_data_text_csv.html create mode 100644 dom/security/test/general/file_empty.html create mode 100644 dom/security/test/general/file_framing_error_pages.sjs create mode 100644 dom/security/test/general/file_framing_error_pages_csp.html create mode 100644 dom/security/test/general/file_framing_error_pages_xfo.html create mode 100644 dom/security/test/general/file_framing_xfo_embed.html create mode 100644 dom/security/test/general/file_framing_xfo_embed_object.sjs create mode 100644 dom/security/test/general/file_framing_xfo_object.html create mode 100644 dom/security/test/general/file_gpc_server.sjs create mode 100644 dom/security/test/general/file_loads_nonscript.html create mode 100644 dom/security/test/general/file_meta_referrer_in_head.html create mode 100644 dom/security/test/general/file_meta_referrer_notin_head.html create mode 100644 dom/security/test/general/file_nonscript create mode 100644 dom/security/test/general/file_nonscript.html create mode 100644 dom/security/test/general/file_nonscript.json create mode 100644 dom/security/test/general/file_nonscript.txt create mode 100644 dom/security/test/general/file_nonscript.xyz create mode 100644 dom/security/test/general/file_nosniff_navigation.sjs create mode 100644 dom/security/test/general/file_nosniff_testserver.sjs create mode 100644 dom/security/test/general/file_same_site_cookies_about.sjs create mode 100644 dom/security/test/general/file_same_site_cookies_blob_iframe_inclusion.html create mode 100644 dom/security/test/general/file_same_site_cookies_blob_iframe_navigation.html create mode 100644 dom/security/test/general/file_same_site_cookies_bug1748693.sjs create mode 100644 dom/security/test/general/file_same_site_cookies_cross_origin_context.sjs create mode 100644 dom/security/test/general/file_same_site_cookies_from_script.sjs create mode 100644 dom/security/test/general/file_same_site_cookies_iframe.sjs create mode 100644 dom/security/test/general/file_same_site_cookies_redirect.sjs create mode 100644 dom/security/test/general/file_same_site_cookies_subrequest.sjs create mode 100644 dom/security/test/general/file_same_site_cookies_toplevel_nav.sjs create mode 100644 dom/security/test/general/file_same_site_cookies_toplevel_set_cookie.sjs create mode 100644 dom/security/test/general/file_script.js create mode 100644 dom/security/test/general/file_toplevel_data_meta_redirect.html create mode 100644 dom/security/test/general/file_toplevel_data_navigations.sjs create mode 100644 dom/security/test/general/file_view_bg_image_data_navigation.html create mode 100644 dom/security/test/general/file_view_image_data_navigation.html create mode 100644 dom/security/test/general/file_xfo_error_page.sjs create mode 100644 dom/security/test/general/mochitest.toml create mode 100644 dom/security/test/general/test_allow_opening_data_json.html create mode 100644 dom/security/test/general/test_allow_opening_data_pdf.html create mode 100644 dom/security/test/general/test_assert_about_page_no_csp.html create mode 100644 dom/security/test/general/test_block_script_wrong_mime.html create mode 100644 dom/security/test/general/test_block_subresource_redir_to_data.html create mode 100644 dom/security/test/general/test_block_toplevel_data_img_navigation.html create mode 100644 dom/security/test/general/test_block_toplevel_data_navigation.html create mode 100644 dom/security/test/general/test_bug1277803.xhtml create mode 100644 dom/security/test/general/test_bug1450853.html create mode 100644 dom/security/test/general/test_bug1660452_http.html create mode 100644 dom/security/test/general/test_bug1660452_https.html create mode 100644 dom/security/test/general/test_cache_split.html create mode 100644 dom/security/test/general/test_contentpolicytype_targeted_link_iframe.html create mode 100644 dom/security/test/general/test_gpc.html create mode 100644 dom/security/test/general/test_innerhtml_sanitizer.html create mode 100644 dom/security/test/general/test_innerhtml_sanitizer.xhtml create mode 100644 dom/security/test/general/test_meta_referrer.html create mode 100644 dom/security/test/general/test_nosniff.html create mode 100644 dom/security/test/general/test_nosniff_navigation.html create mode 100644 dom/security/test/general/test_same_site_cookies_about.html create mode 100644 dom/security/test/general/test_same_site_cookies_cross_origin_context.html create mode 100644 dom/security/test/general/test_same_site_cookies_from_script.html create mode 100644 dom/security/test/general/test_same_site_cookies_iframe.html create mode 100644 dom/security/test/general/test_same_site_cookies_laxByDefault.html create mode 100644 dom/security/test/general/test_same_site_cookies_redirect.html create mode 100644 dom/security/test/general/test_same_site_cookies_subrequest.html create mode 100644 dom/security/test/general/test_same_site_cookies_toplevel_nav.html create mode 100644 dom/security/test/general/test_same_site_cookies_toplevel_set_cookie.html create mode 100644 dom/security/test/general/test_xfo_error_page.html create mode 100644 dom/security/test/general/window_nosniff_navigation.html create mode 100644 dom/security/test/gtest/TestCSPParser.cpp create mode 100644 dom/security/test/gtest/TestFilenameEvalParser.cpp create mode 100644 dom/security/test/gtest/TestSecureContext.cpp create mode 100644 dom/security/test/gtest/TestSmartCrashTrimmer.cpp create mode 100644 dom/security/test/gtest/TestUnexpectedPrivilegedLoads.cpp create mode 100644 dom/security/test/gtest/moz.build create mode 100644 dom/security/test/https-first/browser.toml create mode 100644 dom/security/test/https-first/browser_beforeunload_permit_http.js create mode 100644 dom/security/test/https-first/browser_downgrade_mixed_content_auto_upgrade_console.js create mode 100644 dom/security/test/https-first/browser_downgrade_view_source.js create mode 100644 dom/security/test/https-first/browser_download_attribute.js create mode 100644 dom/security/test/https-first/browser_httpsfirst.js create mode 100644 dom/security/test/https-first/browser_httpsfirst_console_logging.js create mode 100644 dom/security/test/https-first/browser_httpsfirst_speculative_connect.js create mode 100644 dom/security/test/https-first/browser_mixed_content_console.js create mode 100644 dom/security/test/https-first/browser_mixed_content_download.js create mode 100644 dom/security/test/https-first/browser_navigation.js create mode 100644 dom/security/test/https-first/browser_schemeless.js create mode 100644 dom/security/test/https-first/browser_slow_download.js create mode 100644 dom/security/test/https-first/browser_superfluos_auth.js create mode 100644 dom/security/test/https-first/browser_upgrade_onion.js create mode 100644 dom/security/test/https-first/download_page.html create mode 100644 dom/security/test/https-first/download_server.sjs create mode 100644 dom/security/test/https-first/file_bad_cert.sjs create mode 100644 dom/security/test/https-first/file_beforeunload_permit_http.html create mode 100644 dom/security/test/https-first/file_break_endless_upgrade_downgrade_loop.sjs create mode 100644 dom/security/test/https-first/file_data_uri.html create mode 100644 dom/security/test/https-first/file_downgrade_500_responses.sjs create mode 100644 dom/security/test/https-first/file_downgrade_bad_responses.sjs create mode 100644 dom/security/test/https-first/file_downgrade_request_upgrade_request.sjs create mode 100644 dom/security/test/https-first/file_downgrade_view_source.sjs create mode 100644 dom/security/test/https-first/file_downgrade_with_different_path.sjs create mode 100644 dom/security/test/https-first/file_download_attribute.html create mode 100644 dom/security/test/https-first/file_download_attribute.sjs create mode 100644 dom/security/test/https-first/file_form_submission.sjs create mode 100644 dom/security/test/https-first/file_fragment.html create mode 100644 dom/security/test/https-first/file_httpsfirst_speculative_connect.html create mode 100644 dom/security/test/https-first/file_httpsfirst_timeout_server.sjs create mode 100644 dom/security/test/https-first/file_mixed_content_auto_upgrade.html create mode 100644 dom/security/test/https-first/file_mixed_content_console.html create mode 100644 dom/security/test/https-first/file_multiple_redirection.sjs create mode 100644 dom/security/test/https-first/file_navigation.html create mode 100644 dom/security/test/https-first/file_redirect.sjs create mode 100644 dom/security/test/https-first/file_redirect_downgrade.sjs create mode 100644 dom/security/test/https-first/file_referrer_policy.sjs create mode 100644 dom/security/test/https-first/file_slow_download.html create mode 100644 dom/security/test/https-first/file_slow_download.sjs create mode 100644 dom/security/test/https-first/file_toplevel_cookies.sjs create mode 100644 dom/security/test/https-first/file_upgrade_insecure.html create mode 100644 dom/security/test/https-first/file_upgrade_insecure_server.sjs create mode 100644 dom/security/test/https-first/mochitest.toml create mode 100644 dom/security/test/https-first/pass.png create mode 100644 dom/security/test/https-first/test.ogv create mode 100644 dom/security/test/https-first/test.wav create mode 100644 dom/security/test/https-first/test_bad_cert.html create mode 100644 dom/security/test/https-first/test_break_endless_upgrade_downgrade_loop.html create mode 100644 dom/security/test/https-first/test_data_uri.html create mode 100644 dom/security/test/https-first/test_downgrade_500_responses.html create mode 100644 dom/security/test/https-first/test_downgrade_bad_responses.html create mode 100644 dom/security/test/https-first/test_downgrade_request_upgrade_request.html create mode 100644 dom/security/test/https-first/test_form_submission.html create mode 100644 dom/security/test/https-first/test_fragment.html create mode 100644 dom/security/test/https-first/test_multiple_redirection.html create mode 100644 dom/security/test/https-first/test_redirect_downgrade.html create mode 100644 dom/security/test/https-first/test_redirect_upgrade.html create mode 100644 dom/security/test/https-first/test_referrer_policy.html create mode 100644 dom/security/test/https-first/test_resource_upgrade.html create mode 100644 dom/security/test/https-first/test_toplevel_cookies.html create mode 100644 dom/security/test/https-only/browser.toml create mode 100644 dom/security/test/https-only/browser_background_redirect.js create mode 100644 dom/security/test/https-only/browser_bug1874801.js create mode 100644 dom/security/test/https-only/browser_console_logging.js create mode 100644 dom/security/test/https-only/browser_continue_button_delay.js create mode 100644 dom/security/test/https-only/browser_cors_mixedcontent.js create mode 100644 dom/security/test/https-only/browser_hsts_host.js create mode 100644 dom/security/test/https-only/browser_httpsonly_prefs.js create mode 100644 dom/security/test/https-only/browser_httpsonly_speculative_connect.js create mode 100644 dom/security/test/https-only/browser_iframe_test.js create mode 100644 dom/security/test/https-only/browser_navigation.js create mode 100644 dom/security/test/https-only/browser_redirect_tainting.js create mode 100644 dom/security/test/https-only/browser_save_as.js create mode 100644 dom/security/test/https-only/browser_triggering_principal_exemption.js create mode 100644 dom/security/test/https-only/browser_upgrade_exceptions.js create mode 100644 dom/security/test/https-only/browser_upgrade_exemption.js create mode 100644 dom/security/test/https-only/browser_user_gesture.js create mode 100644 dom/security/test/https-only/browser_websocket_exceptions.js create mode 100644 dom/security/test/https-only/file_background_redirect.sjs create mode 100644 dom/security/test/https-only/file_break_endless_upgrade_downgrade_loop.sjs create mode 100644 dom/security/test/https-only/file_bug1874801.html create mode 100644 dom/security/test/https-only/file_bug1874801.sjs create mode 100644 dom/security/test/https-only/file_console_logging.html create mode 100644 dom/security/test/https-only/file_cors_mixedcontent.html create mode 100644 dom/security/test/https-only/file_fragment.html create mode 100644 dom/security/test/https-only/file_fragment_noscript.html create mode 100644 dom/security/test/https-only/file_http_background_auth_request.sjs create mode 100644 dom/security/test/https-only/file_http_background_request.sjs create mode 100644 dom/security/test/https-only/file_httpsonly_speculative_connect.html create mode 100644 dom/security/test/https-only/file_iframe_test.sjs create mode 100644 dom/security/test/https-only/file_insecure_reload.sjs create mode 100644 dom/security/test/https-only/file_redirect.sjs create mode 100644 dom/security/test/https-only/file_redirect_tainting.sjs create mode 100644 dom/security/test/https-only/file_redirect_to_insecure.sjs create mode 100644 dom/security/test/https-only/file_save_as.html create mode 100644 dom/security/test/https-only/file_upgrade_insecure.html create mode 100644 dom/security/test/https-only/file_upgrade_insecure_server.sjs create mode 100644 dom/security/test/https-only/file_upgrade_insecure_wsh.py create mode 100644 dom/security/test/https-only/file_user_gesture.html create mode 100644 dom/security/test/https-only/file_websocket_exceptions.html create mode 100644 dom/security/test/https-only/file_websocket_exceptions_iframe.html create mode 100644 dom/security/test/https-only/hsts_headers.sjs create mode 100644 dom/security/test/https-only/mochitest.toml create mode 100644 dom/security/test/https-only/test_break_endless_upgrade_downgrade_loop.html create mode 100644 dom/security/test/https-only/test_fragment.html create mode 100644 dom/security/test/https-only/test_http_background_auth_request.html create mode 100644 dom/security/test/https-only/test_http_background_request.html create mode 100644 dom/security/test/https-only/test_insecure_reload.html create mode 100644 dom/security/test/https-only/test_redirect_upgrade.html create mode 100644 dom/security/test/https-only/test_resource_upgrade.html create mode 100644 dom/security/test/https-only/test_user_suggestion_box.html create mode 100644 dom/security/test/mixedcontentblocker/auto_upgrading_identity.html create mode 100644 dom/security/test/mixedcontentblocker/auto_upgrading_identity.png create mode 100644 dom/security/test/mixedcontentblocker/browser.toml create mode 100644 dom/security/test/mixedcontentblocker/browser_auto_upgrading_identity.js create mode 100644 dom/security/test/mixedcontentblocker/browser_csp_block_all_mixedcontent_and_mixed_content_display_upgrade.js create mode 100644 dom/security/test/mixedcontentblocker/browser_mixed_content_auth_download.js create mode 100644 dom/security/test/mixedcontentblocker/browser_mixed_content_auto_upgrade_display_console.js create mode 100644 dom/security/test/mixedcontentblocker/browser_test_mixed_content_download.js create mode 100644 dom/security/test/mixedcontentblocker/download_page.html create mode 100644 dom/security/test/mixedcontentblocker/download_server.sjs create mode 100644 dom/security/test/mixedcontentblocker/file_auth_download_page.html create mode 100644 dom/security/test/mixedcontentblocker/file_auth_download_server.sjs create mode 100644 dom/security/test/mixedcontentblocker/file_bug1550792.html create mode 100644 dom/security/test/mixedcontentblocker/file_bug1551886.html create mode 100644 dom/security/test/mixedcontentblocker/file_bug803225_test_mailto.html create mode 100644 dom/security/test/mixedcontentblocker/file_csp_block_all_mixedcontent_and_mixed_content_display_upgrade.html create mode 100644 dom/security/test/mixedcontentblocker/file_frameNavigation.html create mode 100644 dom/security/test/mixedcontentblocker/file_frameNavigation_blankTarget.html create mode 100644 dom/security/test/mixedcontentblocker/file_frameNavigation_grandchild.html create mode 100644 dom/security/test/mixedcontentblocker/file_frameNavigation_innermost.html create mode 100644 dom/security/test/mixedcontentblocker/file_frameNavigation_secure.html create mode 100644 dom/security/test/mixedcontentblocker/file_frameNavigation_secure_grandchild.html create mode 100644 dom/security/test/mixedcontentblocker/file_main.html create mode 100644 dom/security/test/mixedcontentblocker/file_main_bug803225.html create mode 100644 dom/security/test/mixedcontentblocker/file_main_bug803225_websocket_wsh.py create mode 100644 dom/security/test/mixedcontentblocker/file_mixed_content_auto_upgrade_display_console.html create mode 100644 dom/security/test/mixedcontentblocker/file_redirect.html create mode 100644 dom/security/test/mixedcontentblocker/file_redirect_handler.sjs create mode 100644 dom/security/test/mixedcontentblocker/file_server.sjs create mode 100644 dom/security/test/mixedcontentblocker/file_windowOpen.html create mode 100644 dom/security/test/mixedcontentblocker/mochitest.toml create mode 100644 dom/security/test/mixedcontentblocker/pass.png create mode 100644 dom/security/test/mixedcontentblocker/test.ogv create mode 100644 dom/security/test/mixedcontentblocker/test.wav create mode 100644 dom/security/test/mixedcontentblocker/test_bug1550792.html create mode 100644 dom/security/test/mixedcontentblocker/test_bug1551886.html create mode 100644 dom/security/test/mixedcontentblocker/test_bug803225.html create mode 100644 dom/security/test/mixedcontentblocker/test_frameNavigation.html create mode 100644 dom/security/test/mixedcontentblocker/test_main.html create mode 100644 dom/security/test/mixedcontentblocker/test_redirect.html create mode 100644 dom/security/test/mixedcontentblocker/test_windowOpen.html create mode 100644 dom/security/test/moz.build create mode 100644 dom/security/test/referrer-policy/browser.toml create mode 100644 dom/security/test/referrer-policy/browser_fragment_navigation.js create mode 100644 dom/security/test/referrer-policy/browser_referrer_disallow_cross_site_relaxing.js create mode 100644 dom/security/test/referrer-policy/browser_referrer_telemetry.js create mode 100644 dom/security/test/referrer-policy/file_fragment_navigation.sjs create mode 100644 dom/security/test/referrer-policy/img_referrer_testserver.sjs create mode 100644 dom/security/test/referrer-policy/mochitest.toml create mode 100644 dom/security/test/referrer-policy/referrer_header.sjs create mode 100644 dom/security/test/referrer-policy/referrer_header_current_document_iframe.html create mode 100644 dom/security/test/referrer-policy/referrer_helper.js create mode 100644 dom/security/test/referrer-policy/referrer_page.sjs create mode 100644 dom/security/test/referrer-policy/referrer_testserver.sjs create mode 100644 dom/security/test/referrer-policy/test_img_referrer.html create mode 100644 dom/security/test/referrer-policy/test_referrer_header_current_document.html create mode 100644 dom/security/test/referrer-policy/test_referrer_redirect.html create mode 100644 dom/security/test/sec-fetch/browser.toml create mode 100644 dom/security/test/sec-fetch/browser_external_loads.js create mode 100644 dom/security/test/sec-fetch/browser_navigation.js create mode 100644 dom/security/test/sec-fetch/file_dummy_link.html create mode 100644 dom/security/test/sec-fetch/file_dummy_link_location.html create mode 100644 dom/security/test/sec-fetch/file_no_cache.sjs create mode 100644 dom/security/test/sec-fetch/file_redirect.sjs create mode 100644 dom/security/test/sec-fetch/file_trustworthy_loopback.html create mode 100644 dom/security/test/sec-fetch/file_websocket_wsh.py create mode 100644 dom/security/test/sec-fetch/mochitest.toml create mode 100644 dom/security/test/sec-fetch/test_iframe_history_manipulation.html create mode 100644 dom/security/test/sec-fetch/test_iframe_src_metaRedirect.html create mode 100644 dom/security/test/sec-fetch/test_iframe_srcdoc_metaRedirect.html create mode 100644 dom/security/test/sec-fetch/test_iframe_window_open_metaRedirect.html create mode 100644 dom/security/test/sec-fetch/test_trustworthy_loopback.html create mode 100644 dom/security/test/sec-fetch/test_websocket.html create mode 100644 dom/security/test/sri/file_bug_1271796.css create mode 100644 dom/security/test/sri/iframe_script_crossdomain.html create mode 100644 dom/security/test/sri/iframe_script_sameorigin.html create mode 100644 dom/security/test/sri/iframe_style_crossdomain.html create mode 100644 dom/security/test/sri/iframe_style_sameorigin.html create mode 100644 dom/security/test/sri/mochitest.toml create mode 100644 dom/security/test/sri/script.js create mode 100644 dom/security/test/sri/script.js^headers^ create mode 100644 dom/security/test/sri/script_301.js create mode 100644 dom/security/test/sri/script_301.js^headers^ create mode 100644 dom/security/test/sri/script_302.js create mode 100644 dom/security/test/sri/script_302.js^headers^ create mode 100644 dom/security/test/sri/script_401.js create mode 100644 dom/security/test/sri/script_401.js^headers^ create mode 100644 dom/security/test/sri/script_crossdomain1.js create mode 100644 dom/security/test/sri/script_crossdomain1.js^headers^ create mode 100644 dom/security/test/sri/script_crossdomain2.js create mode 100644 dom/security/test/sri/script_crossdomain3.js create mode 100644 dom/security/test/sri/script_crossdomain3.js^headers^ create mode 100644 dom/security/test/sri/script_crossdomain4.js create mode 100644 dom/security/test/sri/script_crossdomain4.js^headers^ create mode 100644 dom/security/test/sri/script_crossdomain5.js create mode 100644 dom/security/test/sri/script_crossdomain5.js^headers^ create mode 100644 dom/security/test/sri/style1.css create mode 100644 dom/security/test/sri/style1.css^headers^ create mode 100644 dom/security/test/sri/style2.css create mode 100644 dom/security/test/sri/style3.css create mode 100644 dom/security/test/sri/style4.css create mode 100644 dom/security/test/sri/style4.css^headers^ create mode 100644 dom/security/test/sri/style5.css create mode 100644 dom/security/test/sri/style6.css create mode 100644 dom/security/test/sri/style6.css^headers^ create mode 100644 dom/security/test/sri/style_301.css create mode 100644 dom/security/test/sri/style_301.css^headers^ create mode 100644 dom/security/test/sri/test_bug_1271796.html create mode 100644 dom/security/test/sri/test_bug_1364262.html create mode 100644 dom/security/test/sri/test_script_crossdomain.html create mode 100644 dom/security/test/sri/test_script_sameorigin.html create mode 100644 dom/security/test/sri/test_style_crossdomain.html create mode 100644 dom/security/test/sri/test_style_sameorigin.html create mode 100644 dom/security/test/unit/test_csp_reports.js create mode 100644 dom/security/test/unit/test_csp_upgrade_insecure_request_header.js create mode 100644 dom/security/test/unit/test_deserialization_format_before_100.js create mode 100644 dom/security/test/unit/test_https_only_https_first_default_port.js create mode 100644 dom/security/test/unit/test_https_only_https_first_prefs.js create mode 100644 dom/security/test/unit/test_isOriginPotentiallyTrustworthy.js create mode 100644 dom/security/test/unit/xpcshell.toml (limited to 'dom/security/test') diff --git a/dom/security/test/cors/browser.toml b/dom/security/test/cors/browser.toml new file mode 100644 index 0000000000..4e69201c66 --- /dev/null +++ b/dom/security/test/cors/browser.toml @@ -0,0 +1,10 @@ +[DEFAULT] +support-files = [ + "file_CrossSiteXHR_server.sjs", + "file_CrossSiteXHR_inner.html", + "file_cors_logging_test.html", + "file_bug1456721.html", + "bug1456721.sjs", +] + +["browser_CORS-console-warnings.js"] diff --git a/dom/security/test/cors/browser_CORS-console-warnings.js b/dom/security/test/cors/browser_CORS-console-warnings.js new file mode 100644 index 0000000000..aa4a211146 --- /dev/null +++ b/dom/security/test/cors/browser_CORS-console-warnings.js @@ -0,0 +1,101 @@ +/* + * Description of the test: + * Ensure that CORS warnings are printed to the web console. + * + * This test uses the same tests as the plain mochitest, but needs access to + * the console. + */ +"use strict"; + +function console_observer(subject, topic, data) { + var message = subject.wrappedJSObject.arguments[0]; + ok(false, message); +} + +var webconsole = null; +var messages_seen = 0; +var expected_messages = 50; + +function on_new_message(msgObj) { + let text = msgObj.message; + + if (text.match("Cross-Origin Request Blocked:")) { + ok(true, "message is: " + text); + messages_seen++; + } +} + +async function do_cleanup() { + Services.console.unregisterListener(on_new_message); + await unsetCookiePref(); +} + +/** + * Set e10s related preferences in the test environment. + * @return {Promise} promise that resolves when preferences are set. + */ +function setCookiePref() { + return new Promise(resolve => + // accept all cookies so that the CORS requests will send the right cookies + SpecialPowers.pushPrefEnv( + { + set: [["network.cookie.cookieBehavior", 0]], + }, + resolve + ) + ); +} + +/** + * Unset e10s related preferences in the test environment. + * @return {Promise} promise that resolves when preferences are unset. + */ +function unsetCookiePref() { + return new Promise(resolve => { + SpecialPowers.popPrefEnv(resolve); + }); +} + +//jscs:disable +add_task(async function () { + //jscs:enable + // A longer timeout is necessary for this test than the plain mochitests + // due to opening a new tab with the web console. + requestLongerTimeout(4); + registerCleanupFunction(do_cleanup); + await setCookiePref(); + Services.console.registerListener(on_new_message); + + let test_uri = + "http://mochi.test:8888/browser/dom/security/test/cors/file_cors_logging_test.html"; + + let tab = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + "about:blank" + ); + + BrowserTestUtils.startLoadingURIString(gBrowser, test_uri); + + await BrowserTestUtils.waitForLocationChange( + gBrowser, + test_uri + "#finished" + ); + + // Different OS combinations + Assert.greater(messages_seen, 0, "Saw " + messages_seen + " messages."); + + messages_seen = 0; + let test_two_uri = + "http://mochi.test:8888/browser/dom/security/test/cors/file_bug1456721.html"; + BrowserTestUtils.startLoadingURIString(gBrowser, test_two_uri); + + await BrowserTestUtils.waitForLocationChange( + gBrowser, + test_two_uri + "#finishedTestTwo" + ); + await BrowserTestUtils.waitForCondition(() => messages_seen > 0); + + Assert.greater(messages_seen, 0, "Saw " + messages_seen + " messages."); + + BrowserTestUtils.removeTab(tab); +}); diff --git a/dom/security/test/cors/bug1456721.sjs b/dom/security/test/cors/bug1456721.sjs new file mode 100644 index 0000000000..de8bd5a7f4 --- /dev/null +++ b/dom/security/test/cors/bug1456721.sjs @@ -0,0 +1,20 @@ +function handleRequest(request, response) { + response.setHeader("Cache-Control", "no-cache", false); + let queryStr = request.queryString; + + if (queryStr === "redirect") { + response.setStatusLine("1.1", 302, "Found"); + response.setHeader("Location", "bug1456721.sjs?load", false); + response.setHeader("Access-Control-Allow-Origin", "*", false); + return; + } + + if (queryStr === "load") { + response.setHeader("Content-Type", "text/html", false); + response.setHeader("Access-Control-Allow-Origin", "*", false); + response.write("foo"); + return; + } + // we should never get here - return something unexpected + response.write("d'oh"); +} diff --git a/dom/security/test/cors/file_CrossSiteXHR_cache_server.sjs b/dom/security/test/cors/file_CrossSiteXHR_cache_server.sjs new file mode 100644 index 0000000000..c8e3243101 --- /dev/null +++ b/dom/security/test/cors/file_CrossSiteXHR_cache_server.sjs @@ -0,0 +1,59 @@ +function handleRequest(request, response) { + var query = {}; + request.queryString.split("&").forEach(function (val) { + var [name, value] = val.split("="); + query[name] = unescape(value); + }); + + if ("setState" in query) { + setState( + "test/dom/security/test_CrossSiteXHR_cache:secData", + query.setState + ); + + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/plain", false); + response.write("hi"); + + return; + } + + var isPreflight = request.method == "OPTIONS"; + + // Send response + + secData = JSON.parse( + getState("test/dom/security/test_CrossSiteXHR_cache:secData") + ); + + if (secData.allowOrigin) { + response.setHeader("Access-Control-Allow-Origin", secData.allowOrigin); + } + + if (secData.withCred) { + response.setHeader("Access-Control-Allow-Credentials", "true"); + } + + if (isPreflight) { + if (secData.allowHeaders) { + response.setHeader("Access-Control-Allow-Headers", secData.allowHeaders); + } + + if (secData.allowMethods) { + response.setHeader("Access-Control-Allow-Methods", secData.allowMethods); + } + + if (secData.cacheTime) { + response.setHeader( + "Access-Control-Max-Age", + secData.cacheTime.toString() + ); + } + + return; + } + + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "application/xml", false); + response.write("hello pass\n"); +} diff --git a/dom/security/test/cors/file_CrossSiteXHR_inner.html b/dom/security/test/cors/file_CrossSiteXHR_inner.html new file mode 100644 index 0000000000..d3e8421362 --- /dev/null +++ b/dom/security/test/cors/file_CrossSiteXHR_inner.html @@ -0,0 +1,121 @@ + + + + + + + + +Inner page + + diff --git a/dom/security/test/cors/file_CrossSiteXHR_inner.jar b/dom/security/test/cors/file_CrossSiteXHR_inner.jar new file mode 100644 index 0000000000..bdb0eb4408 Binary files /dev/null and b/dom/security/test/cors/file_CrossSiteXHR_inner.jar differ diff --git a/dom/security/test/cors/file_CrossSiteXHR_inner_data.sjs b/dom/security/test/cors/file_CrossSiteXHR_inner_data.sjs new file mode 100644 index 0000000000..4a030c4211 --- /dev/null +++ b/dom/security/test/cors/file_CrossSiteXHR_inner_data.sjs @@ -0,0 +1,103 @@ +var data = + '\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +Inner page\n\ +\n\ +'; + +function handleRequest(request, response) { + response.setStatusLine(null, 302, "Follow me"); + response.setHeader("Location", "data:text/html," + escape(data)); + response.setHeader("Content-Type", "text/plain"); + response.write("Follow that guy!"); +} diff --git a/dom/security/test/cors/file_CrossSiteXHR_server.sjs b/dom/security/test/cors/file_CrossSiteXHR_server.sjs new file mode 100644 index 0000000000..a3129de75f --- /dev/null +++ b/dom/security/test/cors/file_CrossSiteXHR_server.sjs @@ -0,0 +1,230 @@ +const CC = Components.Constructor; +const BinaryInputStream = CC( + "@mozilla.org/binaryinputstream;1", + "nsIBinaryInputStream", + "setInputStream" +); +Services.prefs.setBoolPref("security.allow_eval_with_system_principal", true); + +// eslint-disable-next-line complexity +function handleRequest(request, response) { + var query = {}; + request.queryString.split("&").forEach(function (val) { + var [name, value] = val.split("="); + query[name] = unescape(value); + }); + + var isPreflight = request.method == "OPTIONS"; + + var bodyStream = new BinaryInputStream(request.bodyInputStream); + var bodyBytes = []; + while ((bodyAvail = bodyStream.available()) > 0) { + Array.prototype.push.apply(bodyBytes, bodyStream.readByteArray(bodyAvail)); + } + + var body = decodeURIComponent( + escape(String.fromCharCode.apply(null, bodyBytes)) + ); + + if (query.hop) { + query.hop = parseInt(query.hop, 10); + hops = JSON.parse(query.hops); + var curHop = hops[query.hop - 1]; + query.allowOrigin = curHop.allowOrigin; + query.allowHeaders = curHop.allowHeaders; + query.allowMethods = curHop.allowMethods; + query.allowCred = curHop.allowCred; + query.noAllowPreflight = curHop.noAllowPreflight; + if (curHop.setCookie) { + query.setCookie = unescape(curHop.setCookie); + } + if (curHop.cookie) { + query.cookie = unescape(curHop.cookie); + } + query.noCookie = curHop.noCookie; + } + + // Check that request was correct + + if (!isPreflight && query.body && body != query.body) { + sendHttp500( + response, + "Wrong body. Expected " + query.body + " got " + body + ); + return; + } + + if (!isPreflight && "headers" in query) { + headers = JSON.parse(query.headers); + for (headerName in headers) { + // Content-Type is changed if there was a body + if ( + !(headerName == "Content-Type" && body) && + (!request.hasHeader(headerName) || + request.getHeader(headerName) != headers[headerName]) + ) { + var actual = request.hasHeader(headerName) + ? request.getHeader(headerName) + : ""; + sendHttp500( + response, + "Header " + + headerName + + " had wrong value. Expected " + + headers[headerName] + + " got " + + actual + ); + return; + } + } + } + + if ( + isPreflight && + "requestHeaders" in query && + request.getHeader("Access-Control-Request-Headers") != query.requestHeaders + ) { + sendHttp500( + response, + "Access-Control-Request-Headers had wrong value. Expected " + + query.requestHeaders + + " got " + + request.getHeader("Access-Control-Request-Headers") + ); + return; + } + + if ( + isPreflight && + "requestMethod" in query && + request.getHeader("Access-Control-Request-Method") != query.requestMethod + ) { + sendHttp500( + response, + "Access-Control-Request-Method had wrong value. Expected " + + query.requestMethod + + " got " + + request.getHeader("Access-Control-Request-Method") + ); + return; + } + + if ("origin" in query && request.getHeader("Origin") != query.origin) { + sendHttp500( + response, + "Origin had wrong value. Expected " + + query.origin + + " got " + + request.getHeader("Origin") + ); + return; + } + + if ("cookie" in query) { + cookies = {}; + request + .getHeader("Cookie") + .split(/ *; */) + .forEach(function (val) { + var [name, value] = val.split("="); + cookies[name] = unescape(value); + }); + + query.cookie.split(",").forEach(function (val) { + var [name, value] = val.split("="); + if (cookies[name] != value) { + sendHttp500( + response, + "Cookie " + + name + + " had wrong value. Expected " + + value + + " got " + + cookies[name] + ); + } + }); + } + + if (query.noCookie && request.hasHeader("Cookie")) { + sendHttp500( + response, + "Got cookies when didn't expect to: " + request.getHeader("Cookie") + ); + return; + } + + // Send response + + if (!isPreflight && query.status) { + response.setStatusLine(null, query.status, query.statusMessage); + } + if (isPreflight && query.preflightStatus) { + response.setStatusLine(null, query.preflightStatus, "preflight status"); + } + + if (query.allowOrigin && (!isPreflight || !query.noAllowPreflight)) { + response.setHeader("Access-Control-Allow-Origin", query.allowOrigin); + } + + if (query.allowCred) { + response.setHeader("Access-Control-Allow-Credentials", "true"); + } + + if (query.setCookie) { + response.setHeader("Set-Cookie", query.setCookie + "; path=/"); + } + + if (isPreflight) { + if (query.allowHeaders) { + response.setHeader("Access-Control-Allow-Headers", query.allowHeaders); + } + + if (query.allowMethods) { + response.setHeader("Access-Control-Allow-Methods", query.allowMethods); + } + } else { + if (query.responseHeaders) { + let responseHeaders = JSON.parse(query.responseHeaders); + for (let responseHeader in responseHeaders) { + response.setHeader(responseHeader, responseHeaders[responseHeader]); + } + } + + if (query.exposeHeaders) { + response.setHeader("Access-Control-Expose-Headers", query.exposeHeaders); + } + } + + if (!isPreflight && query.hop && query.hop < hops.length) { + newURL = + hops[query.hop].server + + "/tests/dom/security/test/cors/file_CrossSiteXHR_server.sjs?" + + "hop=" + + (query.hop + 1) + + "&hops=" + + escape(query.hops); + if ("headers" in query) { + newURL += "&headers=" + escape(query.headers); + } + response.setStatusLine(null, 307, "redirect"); + response.setHeader("Location", newURL); + + return; + } + + // Send response body + if (!isPreflight && request.method != "HEAD") { + response.setHeader("Content-Type", "application/xml", false); + response.write("hello pass\n"); + } + if (isPreflight && "preflightBody" in query) { + response.setHeader("Content-Type", "text/plain", false); + response.write(query.preflightBody); + } +} + +function sendHttp500(response, text) { + response.setStatusLine(null, 500, text); +} diff --git a/dom/security/test/cors/file_bug1456721.html b/dom/security/test/cors/file_bug1456721.html new file mode 100644 index 0000000000..8926b6ffc1 --- /dev/null +++ b/dom/security/test/cors/file_bug1456721.html @@ -0,0 +1,74 @@ + + + + + Test new CORS console messages + + +

+ +

+ +
+
+
+ + diff --git a/dom/security/test/cors/file_cors_logging_test.html b/dom/security/test/cors/file_cors_logging_test.html new file mode 100644 index 0000000000..d29f93cf9c --- /dev/null +++ b/dom/security/test/cors/file_cors_logging_test.html @@ -0,0 +1,1311 @@ + + + + + Test for Cross Site XMLHttpRequest + + +

+ +

+ +
+
+
+ + diff --git a/dom/security/test/cors/file_cors_logging_test.html.css b/dom/security/test/cors/file_cors_logging_test.html.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/dom/security/test/cors/mochitest.toml b/dom/security/test/cors/mochitest.toml new file mode 100644 index 0000000000..b46def07ea --- /dev/null +++ b/dom/security/test/cors/mochitest.toml @@ -0,0 +1,26 @@ +[DEFAULT] +support-files = [ + "file_CrossSiteXHR_cache_server.sjs", + "file_CrossSiteXHR_inner.html", + "file_CrossSiteXHR_inner_data.sjs", + "file_CrossSiteXHR_server.sjs", +] + +["test_CrossSiteXHR.html"] +skip-if = [ + "http3", + "http2", +] + +["test_CrossSiteXHR_cache.html"] +skip-if = [ + "http3", + "http2", +] + +["test_CrossSiteXHR_origin.html"] +skip-if = [ + "http3", + "http2", +] + diff --git a/dom/security/test/cors/test_CrossSiteXHR.html b/dom/security/test/cors/test_CrossSiteXHR.html new file mode 100644 index 0000000000..f92571c6f8 --- /dev/null +++ b/dom/security/test/cors/test_CrossSiteXHR.html @@ -0,0 +1,1549 @@ + + + + + Test for Cross Site XMLHttpRequest + + + + +

+ +

+ +
+
+
+ + diff --git a/dom/security/test/cors/test_CrossSiteXHR_cache.html b/dom/security/test/cors/test_CrossSiteXHR_cache.html new file mode 100644 index 0000000000..77898e38ed --- /dev/null +++ b/dom/security/test/cors/test_CrossSiteXHR_cache.html @@ -0,0 +1,610 @@ + + + + + Test for Cross Site XMLHttpRequest + + + + +

+ +

+ +
+
+
+ + diff --git a/dom/security/test/cors/test_CrossSiteXHR_origin.html b/dom/security/test/cors/test_CrossSiteXHR_origin.html new file mode 100644 index 0000000000..ba4a645965 --- /dev/null +++ b/dom/security/test/cors/test_CrossSiteXHR_origin.html @@ -0,0 +1,180 @@ + + + + + Test for Cross Site XMLHttpRequest + + + + +

+ +

+ +
+
+
+ + diff --git a/dom/security/test/crashtests/1577572.html b/dom/security/test/crashtests/1577572.html new file mode 100644 index 0000000000..732c7aa5dc --- /dev/null +++ b/dom/security/test/crashtests/1577572.html @@ -0,0 +1,10 @@ + +Bug 1577572 + + + + + + Bug 1577572 + + diff --git a/dom/security/test/crashtests/1583044.html b/dom/security/test/crashtests/1583044.html new file mode 100644 index 0000000000..aa6d496d64 --- /dev/null +++ b/dom/security/test/crashtests/1583044.html @@ -0,0 +1,11 @@ + + +Bug 1583044 + + + + diff --git a/dom/security/test/crashtests/crashtests.list b/dom/security/test/crashtests/crashtests.list new file mode 100644 index 0000000000..fc7986cf3d --- /dev/null +++ b/dom/security/test/crashtests/crashtests.list @@ -0,0 +1,2 @@ +load 1583044.html +load 1577572.html diff --git a/dom/security/test/csp/Ahem.ttf b/dom/security/test/csp/Ahem.ttf new file mode 100644 index 0000000000..ac81cb0316 Binary files /dev/null and b/dom/security/test/csp/Ahem.ttf differ diff --git a/dom/security/test/csp/File b/dom/security/test/csp/File new file mode 100644 index 0000000000..e69de29bb2 diff --git a/dom/security/test/csp/browser.toml b/dom/security/test/csp/browser.toml new file mode 100644 index 0000000000..403be75533 --- /dev/null +++ b/dom/security/test/csp/browser.toml @@ -0,0 +1,30 @@ +[DEFAULT] +support-files = [ + "!/dom/security/test/csp/file_testserver.sjs", + "!/dom/security/test/csp/file_web_manifest.html", + "!/dom/security/test/csp/file_web_manifest.json", + "!/dom/security/test/csp/file_web_manifest.json^headers^", + "!/dom/security/test/csp/file_web_manifest_https.html", + "!/dom/security/test/csp/file_web_manifest_https.json", + "!/dom/security/test/csp/file_web_manifest_mixed_content.html", + "!/dom/security/test/csp/file_web_manifest_remote.html", + "file_test_browser_bookmarklets.html", + "file_test_browser_bookmarklets.html^headers^", +] + +["browser_manifest-src-override-default-src.js"] + +["browser_pdfjs_not_subject_to_csp.js"] +support-files = [ + "dummy.pdf", + "file_pdfjs_not_subject_to_csp.html", +] + +["browser_test_bookmarklets.js"] + +["browser_test_uir_optional_clicks.js"] +support-files = ["file_csp_meta_uir.html"] + +["browser_test_web_manifest.js"] + +["browser_test_web_manifest_mixed_content.js"] diff --git a/dom/security/test/csp/browser_manifest-src-override-default-src.js b/dom/security/test/csp/browser_manifest-src-override-default-src.js new file mode 100644 index 0000000000..5eef5bcc4e --- /dev/null +++ b/dom/security/test/csp/browser_manifest-src-override-default-src.js @@ -0,0 +1,126 @@ +/* + * Description of the tests: + * Tests check that default-src can be overridden by manifest-src. + */ +/*globals Cu, is, ok*/ +"use strict"; +const { ManifestObtainer } = ChromeUtils.importESModule( + "resource://gre/modules/ManifestObtainer.sys.mjs" +); +const path = "/tests/dom/security/test/csp/"; +const testFile = `${path}file_web_manifest.html`; +const mixedContentFile = `${path}file_web_manifest_mixed_content.html`; +const server = `${path}file_testserver.sjs`; +const defaultURL = new URL(`https://example.org${server}`); +const mixedURL = new URL(`http://mochi.test:8888${server}`); + +// Enable web manifest processing. +Services.prefs.setBoolPref("dom.manifest.enabled", true); + +const tests = [ + // Check interaction with default-src and another origin, + // CSP allows fetching from example.org, so manifest should load. + { + expected: `CSP manifest-src overrides default-src of elsewhere.com`, + get tabURL() { + const url = new URL(defaultURL); + url.searchParams.append("file", testFile); + url.searchParams.append("cors", "*"); + url.searchParams.append( + "csp", + "default-src http://elsewhere.com; manifest-src http://example.org" + ); + return url.href; + }, + run(manifest) { + is(manifest.name, "loaded", this.expected); + }, + }, + // Check interaction with default-src none, + // CSP allows fetching manifest from example.org, so manifest should load. + { + expected: `CSP manifest-src overrides default-src`, + get tabURL() { + const url = new URL(mixedURL); + url.searchParams.append("file", mixedContentFile); + url.searchParams.append("cors", "http://test:80"); + url.searchParams.append( + "csp", + "default-src 'self'; manifest-src http://test:80" + ); + return url.href; + }, + run(manifest) { + is(manifest.name, "loaded", this.expected); + }, + }, +]; + +//jscs:disable +add_task(async function () { + //jscs:enable + const testPromises = tests.map(test => { + const tabOptions = { + gBrowser, + url: test.tabURL, + skipAnimation: true, + }; + return BrowserTestUtils.withNewTab(tabOptions, browser => + testObtainingManifest(browser, test) + ); + }); + await Promise.all(testPromises); +}); + +async function testObtainingManifest(aBrowser, aTest) { + const expectsBlocked = aTest.expected.includes("block"); + const observer = expectsBlocked ? createNetObserver(aTest) : null; + // Expect an exception (from promise rejection) if there a content policy + // that is violated. + try { + const manifest = await ManifestObtainer.browserObtainManifest(aBrowser); + aTest.run(manifest); + } catch (e) { + const wasBlocked = e.message.includes( + "NetworkError when attempting to fetch resource" + ); + ok( + wasBlocked, + `Expected promise rejection obtaining ${aTest.tabURL}: ${e.message}` + ); + if (observer) { + await observer.untilFinished; + } + } +} + +// Helper object used to observe policy violations. It waits 1 seconds +// for a response, and then times out causing its associated test to fail. +function createNetObserver(test) { + let finishedTest; + let success = false; + const finished = new Promise(resolver => { + finishedTest = resolver; + }); + // eslint-disable-next-line mozilla/no-arbitrary-setTimeout + const timeoutId = setTimeout(() => { + if (!success) { + test.run("This test timed out."); + finishedTest(); + } + }, 1000); + var observer = { + get untilFinished() { + return finished; + }, + observe(subject, topic) { + SpecialPowers.removeObserver(observer, "csp-on-violate-policy"); + test.run(topic); + finishedTest(); + clearTimeout(timeoutId); + success = true; + }, + }; + SpecialPowers.addObserver(observer, "csp-on-violate-policy"); + return observer; +} diff --git a/dom/security/test/csp/browser_pdfjs_not_subject_to_csp.js b/dom/security/test/csp/browser_pdfjs_not_subject_to_csp.js new file mode 100644 index 0000000000..2391e955ba --- /dev/null +++ b/dom/security/test/csp/browser_pdfjs_not_subject_to_csp.js @@ -0,0 +1,45 @@ +"use strict"; + +const TEST_PATH = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "https://example.com" +); + +add_task(async function () { + await BrowserTestUtils.withNewTab( + TEST_PATH + "file_pdfjs_not_subject_to_csp.html", + async function (browser) { + let pdfPromise = BrowserTestUtils.waitForContentEvent( + browser, + "documentloaded", + false, + null, + true + ); + + await ContentTask.spawn(browser, {}, async function () { + let pdfButton = content.document.getElementById("pdfButton"); + pdfButton.click(); + }); + + await pdfPromise; + + await ContentTask.spawn(browser, {}, async function () { + let pdfFrame = content.document.getElementById("pdfFrame"); + // 1) Sanity that we have loaded the PDF using a blob + ok(pdfFrame.src.startsWith("blob:"), "it's a blob URL"); + + // 2) Ensure that the PDF has actually loaded + ok( + pdfFrame.contentDocument.querySelector("div#viewer"), + "document content has viewer UI" + ); + + // 3) Ensure we have the correct CSP attached + let cspJSON = pdfFrame.contentDocument.cspJSON; + ok(cspJSON.includes("script-src"), "found script-src directive"); + ok(cspJSON.includes("allowPDF"), "found script-src nonce value"); + }); + } + ); +}); diff --git a/dom/security/test/csp/browser_test_bookmarklets.js b/dom/security/test/csp/browser_test_bookmarklets.js new file mode 100644 index 0000000000..08b5ab0758 --- /dev/null +++ b/dom/security/test/csp/browser_test_bookmarklets.js @@ -0,0 +1,82 @@ +"use strict"; + +let BASE_URL = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content/", + "https://example.com/" +); +const DUMMY_URL = BASE_URL + "file_test_browser_bookmarklets.html"; + +function makeBookmarkFor(url, keyword) { + return Promise.all([ + PlacesUtils.bookmarks.insert({ + parentGuid: PlacesUtils.bookmarks.unfiledGuid, + title: "bookmarklet", + url, + }), + PlacesUtils.keywords.insert({ url, keyword }), + ]); +} +/* Test Description: + * 1 - Load a Page with CSP script-src: none + * 2 - Create a bookmarklet with javascript:window.open('about:blank') + * 3 - Select and enter the bookmarklet + * A new tab with about:blank should be opened + */ +add_task(async function openKeywordBookmarkWithWindowOpen() { + // This is the current default, but let's not assume that... + await SpecialPowers.pushPrefEnv({ + set: [ + ["browser.link.open_newwindow", 3], + ["dom.disable_open_during_load", true], + ], + }); + + let moztab; + let tabOpened = BrowserTestUtils.openNewForegroundTab( + gBrowser, + DUMMY_URL + ).then(tab => { + moztab = tab; + }); + let keywordForBM = "openNewWindowBookmarklet"; + + let bookmarkInfo; + let bookmarkCreated = makeBookmarkFor( + `javascript: window.open("about:blank")`, + keywordForBM + ).then(values => { + bookmarkInfo = values[0]; + }); + await Promise.all([tabOpened, bookmarkCreated]); + + registerCleanupFunction(function () { + return Promise.all([ + PlacesUtils.bookmarks.remove(bookmarkInfo), + PlacesUtils.keywords.remove(keywordForBM), + ]); + }); + gURLBar.value = keywordForBM; + gURLBar.focus(); + + let tabCreatedPromise = BrowserTestUtils.waitForEvent( + gBrowser.tabContainer, + "TabOpen" + ); + EventUtils.synthesizeKey("KEY_Enter"); + info("Waiting for tab being created"); + let { target: tab } = await tabCreatedPromise; + info("Got tab"); + let browser = tab.linkedBrowser; + if (!browser.currentURI || browser.currentURI.spec != "about:blank") { + info("Waiting for browser load"); + await BrowserTestUtils.browserLoaded(browser, false, "about:blank"); + } + is( + browser.currentURI && browser.currentURI.spec, + "about:blank", + "Tab with expected URL loaded." + ); + info("Waiting to remove tab"); + BrowserTestUtils.removeTab(tab); + BrowserTestUtils.removeTab(moztab); +}); diff --git a/dom/security/test/csp/browser_test_uir_optional_clicks.js b/dom/security/test/csp/browser_test_uir_optional_clicks.js new file mode 100644 index 0000000000..57e1f64f1a --- /dev/null +++ b/dom/security/test/csp/browser_test_uir_optional_clicks.js @@ -0,0 +1,36 @@ +"use strict"; + +const TEST_PATH_HTTP = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "http://example.com" +); +const TEST_PATH_HTTPS = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "https://example.com" +); + +add_task(async function () { + await SpecialPowers.pushPrefEnv({ + set: [["dom.security.https_first", false]], + }); + await BrowserTestUtils.withNewTab( + TEST_PATH_HTTPS + "file_csp_meta_uir.html", + async function (browser) { + let newTabPromise = BrowserTestUtils.waitForNewTab(gBrowser, null, true); + BrowserTestUtils.synthesizeMouse( + "#mylink", + 2, + 2, + { accelKey: true }, + browser + ); + let tab = await newTabPromise; + is( + tab.linkedBrowser.currentURI.scheme, + "https", + "Should have opened https page." + ); + BrowserTestUtils.removeTab(tab); + } + ); +}); diff --git a/dom/security/test/csp/browser_test_web_manifest.js b/dom/security/test/csp/browser_test_web_manifest.js new file mode 100644 index 0000000000..bdf62ab397 --- /dev/null +++ b/dom/security/test/csp/browser_test_web_manifest.js @@ -0,0 +1,239 @@ +/* + * Description of the tests: + * These tests check for conformance to the CSP spec as they relate to Web Manifests. + * + * In particular, the tests check that default-src and manifest-src directives are + * are respected by the ManifestObtainer. + */ +/*globals Cu, is, ok*/ +"use strict"; +const { ManifestObtainer } = ChromeUtils.importESModule( + "resource://gre/modules/ManifestObtainer.sys.mjs" +); +const path = "/tests/dom/security/test/csp/"; +const testFile = `${path}file_web_manifest.html`; +const remoteFile = `${path}file_web_manifest_remote.html`; +const httpsManifest = `${path}file_web_manifest_https.html`; +const server = `${path}file_testserver.sjs`; +const defaultURL = new URL(`http://example.org${server}`); +const secureURL = new URL(`https://example.com:443${server}`); + +// Enable web manifest processing. +Services.prefs.setBoolPref("dom.manifest.enabled", true); + +const tests = [ + // CSP block everything, so trying to load a manifest + // will result in a policy violation. + { + expected: "default-src 'none' blocks fetching manifest.", + get tabURL() { + const url = new URL(defaultURL); + url.searchParams.append("file", testFile); + url.searchParams.append("csp", "default-src 'none'"); + return url.href; + }, + run(topic) { + is(topic, "csp-on-violate-policy", this.expected); + }, + }, + // CSP allows fetching only from mochi.test:8888, + // so trying to load a manifest from same origin + // triggers a CSP violation. + { + expected: "default-src mochi.test:8888 blocks manifest fetching.", + get tabURL() { + const url = new URL(defaultURL); + url.searchParams.append("file", testFile); + url.searchParams.append("csp", "default-src mochi.test:8888"); + return url.href; + }, + run(topic) { + is(topic, "csp-on-violate-policy", this.expected); + }, + }, + // CSP restricts fetching to 'self', so allowing the manifest + // to load. The name of the manifest is then checked. + { + expected: "CSP default-src 'self' allows fetch of manifest.", + get tabURL() { + const url = new URL(defaultURL); + url.searchParams.append("file", testFile); + url.searchParams.append("csp", "default-src 'self'"); + return url.href; + }, + run(manifest) { + is(manifest.name, "loaded", this.expected); + }, + }, + // CSP only allows fetching from mochi.test:8888 and remoteFile + // requests a manifest from that origin, so manifest should load. + { + expected: "CSP default-src mochi.test:8888 allows fetching manifest.", + get tabURL() { + const url = new URL(defaultURL); + url.searchParams.append("file", remoteFile); + url.searchParams.append("csp", "default-src http://mochi.test:8888"); + return url.href; + }, + run(manifest) { + is(manifest.name, "loaded", this.expected); + }, + }, + // default-src blocks everything, so any attempt to + // fetch a manifest from another origin will trigger a + // policy violation. + { + expected: "default-src 'none' blocks mochi.test:8888", + get tabURL() { + const url = new URL(defaultURL); + url.searchParams.append("file", remoteFile); + url.searchParams.append("csp", "default-src 'none'"); + return url.href; + }, + run(topic) { + is(topic, "csp-on-violate-policy", this.expected); + }, + }, + // CSP allows fetching from self, so manifest should load. + { + expected: "CSP manifest-src allows self", + get tabURL() { + const url = new URL(defaultURL); + url.searchParams.append("file", testFile); + url.searchParams.append("csp", "manifest-src 'self'"); + return url.href; + }, + run(manifest) { + is(manifest.name, "loaded", this.expected); + }, + }, + // CSP allows fetching from example.org, so manifest should load. + { + expected: "CSP manifest-src allows http://example.org", + get tabURL() { + const url = new URL(defaultURL); + url.searchParams.append("file", testFile); + url.searchParams.append("csp", "manifest-src http://example.org"); + return url.href; + }, + run(manifest) { + is(manifest.name, "loaded", this.expected); + }, + }, + { + expected: "CSP manifest-src allows mochi.test:8888", + get tabURL() { + const url = new URL(defaultURL); + url.searchParams.append("file", remoteFile); + url.searchParams.append("cors", "*"); + url.searchParams.append( + "csp", + "default-src *; manifest-src http://mochi.test:8888" + ); + return url.href; + }, + run(manifest) { + is(manifest.name, "loaded", this.expected); + }, + }, + // CSP restricts fetching to mochi.test:8888, but the test + // file is at example.org. Hence, a policy violation is + // triggered. + { + expected: "CSP blocks manifest fetching from example.org.", + get tabURL() { + const url = new URL(defaultURL); + url.searchParams.append("file", testFile); + url.searchParams.append("csp", "manifest-src mochi.test:8888"); + return url.href; + }, + run(topic) { + is(topic, "csp-on-violate-policy", this.expected); + }, + }, + // CSP is set to only allow manifest to be loaded from same origin, + // but the remote file attempts to load from a different origin. Thus + // this causes a CSP violation. + { + expected: "CSP manifest-src 'self' blocks cross-origin fetch.", + get tabURL() { + const url = new URL(defaultURL); + url.searchParams.append("file", remoteFile); + url.searchParams.append("csp", "manifest-src 'self'"); + return url.href; + }, + run(topic) { + is(topic, "csp-on-violate-policy", this.expected); + }, + }, + // CSP allows fetching over TLS from example.org, so manifest should load. + { + expected: "CSP manifest-src allows example.com over TLS", + get tabURL() { + // secureURL loads https://example.com:443 + // and gets manifest from https://example.org:443 + const url = new URL(secureURL); + url.searchParams.append("file", httpsManifest); + url.searchParams.append("cors", "*"); + url.searchParams.append("csp", "manifest-src https://example.com:443"); + return url.href; + }, + run(manifest) { + is(manifest.name, "loaded", this.expected); + }, + }, +]; + +//jscs:disable +add_task(async function () { + //jscs:enable + const testPromises = tests.map(test => { + const tabOptions = { + gBrowser, + url: test.tabURL, + skipAnimation: true, + }; + return BrowserTestUtils.withNewTab(tabOptions, browser => + testObtainingManifest(browser, test) + ); + }); + await Promise.all(testPromises); +}); + +async function testObtainingManifest(aBrowser, aTest) { + const waitForObserver = waitForNetObserver(aBrowser, aTest); + // Expect an exception (from promise rejection) if there a content policy + // that is violated. + try { + const manifest = await ManifestObtainer.browserObtainManifest(aBrowser); + aTest.run(manifest); + } catch (e) { + const wasBlocked = e.message.includes( + "NetworkError when attempting to fetch resource" + ); + ok( + wasBlocked, + `Expected promise rejection obtaining ${aTest.tabURL}: ${e.message}` + ); + } finally { + await waitForObserver; + } +} + +// Helper object used to observe policy violations when blocking is expected. +function waitForNetObserver(aBrowser, aTest) { + // We don't need to wait for violation, so just resolve + if (!aTest.expected.includes("block")) { + return Promise.resolve(); + } + + return ContentTask.spawn(aBrowser, [], () => { + return new Promise(resolve => { + function observe(subject, topic) { + Services.obs.removeObserver(observe, "csp-on-violate-policy"); + resolve(); + } + Services.obs.addObserver(observe, "csp-on-violate-policy"); + }); + }).then(() => aTest.run("csp-on-violate-policy")); +} diff --git a/dom/security/test/csp/browser_test_web_manifest_mixed_content.js b/dom/security/test/csp/browser_test_web_manifest_mixed_content.js new file mode 100644 index 0000000000..0cf55b80e3 --- /dev/null +++ b/dom/security/test/csp/browser_test_web_manifest_mixed_content.js @@ -0,0 +1,57 @@ +/* + * Description of the test: + * Check that mixed content blocker works prevents fetches of + * mixed content manifests. + */ +/*globals Cu, ok*/ +"use strict"; +const { ManifestObtainer } = ChromeUtils.importESModule( + "resource://gre/modules/ManifestObtainer.sys.mjs" +); +const path = "/tests/dom/security/test/csp/"; +const mixedContent = `${path}file_web_manifest_mixed_content.html`; +const server = `${path}file_testserver.sjs`; +const secureURL = new URL(`https://example.com${server}`); +const tests = [ + // Trying to load mixed content in file_web_manifest_mixed_content.html + // needs to result in an error. + { + expected: "Mixed Content Blocker prevents fetching manifest.", + get tabURL() { + const url = new URL(secureURL); + url.searchParams.append("file", mixedContent); + return url.href; + }, + run(error) { + // Check reason for error. + const check = /NetworkError when attempting to fetch resource/.test( + error.message + ); + ok(check, this.expected); + }, + }, +]; + +//jscs:disable +add_task(async function () { + //jscs:enable + const testPromises = tests.map(test => { + const tabOptions = { + gBrowser, + url: test.tabURL, + skipAnimation: true, + }; + return BrowserTestUtils.withNewTab(tabOptions, browser => + testObtainingManifest(browser, test) + ); + }); + await Promise.all(testPromises); +}); + +async function testObtainingManifest(aBrowser, aTest) { + try { + await ManifestObtainer.browserObtainManifest(aBrowser); + } catch (e) { + aTest.run(e); + } +} diff --git a/dom/security/test/csp/dummy.pdf b/dom/security/test/csp/dummy.pdf new file mode 100644 index 0000000000..7ad87e3c2e Binary files /dev/null and b/dom/security/test/csp/dummy.pdf differ diff --git a/dom/security/test/csp/file_CSP.css b/dom/security/test/csp/file_CSP.css new file mode 100644 index 0000000000..6835c4d4ad --- /dev/null +++ b/dom/security/test/csp/file_CSP.css @@ -0,0 +1,20 @@ +/* + * Moved this CSS from an inline stylesheet to an external file when we added + * inline-style blocking in bug 763879. + * This test may hang if the load for this .css file is blocked due to a + * malfunction of CSP, but should pass if the style_good test passes. + */ + +/* CSS font embedding tests */ +@font-face { + font-family: "arbitrary_good"; + src: url('file_CSP.sjs?testid=font_good&type=application/octet-stream'); +} +@font-face { + font-family: "arbitrary_bad"; + src: url('http://example.org/tests/dom/security/test/csp/file_CSP.sjs?testid=font_bad&type=application/octet-stream'); +} + +.div_arbitrary_good { font-family: "arbitrary_good"; } +.div_arbitrary_bad { font-family: "arbitrary_bad"; } + diff --git a/dom/security/test/csp/file_CSP.sjs b/dom/security/test/csp/file_CSP.sjs new file mode 100644 index 0000000000..ff41690078 --- /dev/null +++ b/dom/security/test/csp/file_CSP.sjs @@ -0,0 +1,24 @@ +// SJS file for CSP mochitests + +function handleRequest(request, response) { + var query = {}; + request.queryString.split("&").forEach(function (val) { + var [name, value] = val.split("="); + query[name] = unescape(value); + }); + + var isPreflight = request.method == "OPTIONS"; + + //avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + if ("type" in query) { + response.setHeader("Content-Type", unescape(query.type), false); + } else { + response.setHeader("Content-Type", "text/html", false); + } + + if ("content" in query) { + response.write(unescape(query.content)); + } +} diff --git a/dom/security/test/csp/file_allow_https_schemes.html b/dom/security/test/csp/file_allow_https_schemes.html new file mode 100644 index 0000000000..787e683e87 --- /dev/null +++ b/dom/security/test/csp/file_allow_https_schemes.html @@ -0,0 +1,14 @@ + + + + Bug 826805 - CSP: Allow http and https for scheme-less sources + + +
blocked
+ + + + diff --git a/dom/security/test/csp/file_base_uri_server.sjs b/dom/security/test/csp/file_base_uri_server.sjs new file mode 100644 index 0000000000..9056c8bbfd --- /dev/null +++ b/dom/security/test/csp/file_base_uri_server.sjs @@ -0,0 +1,58 @@ +// Custom *.sjs file specifically for the needs of +// https://bugzilla.mozilla.org/show_bug.cgi?id=1263286 + +"use strict"; + +const PRE_BASE = ` + + + + Bug 1045897 - Test CSP base-uri directive`; + +const REGULAR_POST_BASE = ` + + + + + `; + +const SCRIPT_POST_BASE = ` + + + + + `; + +function handleRequest(request, response) { + const query = new URLSearchParams(request.queryString); + + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + // Deliver the CSP policy encoded in the URL + response.setHeader("Content-Security-Policy", query.get("csp"), false); + + // Send HTML to test allowed/blocked behaviors + response.setHeader("Content-Type", "text/html", false); + response.write(PRE_BASE); + var base1 = ''; + var base2 = ''; + response.write(base1 + base2); + + if (query.get("action") === "enforce-csp") { + response.write(REGULAR_POST_BASE); + return; + } + + if (query.get("action") === "remove-base1") { + response.write(SCRIPT_POST_BASE); + return; + } + + // we should never get here, but just in case + // return something unexpected + response.write("do'h"); +} diff --git a/dom/security/test/csp/file_blob_data_schemes.html b/dom/security/test/csp/file_blob_data_schemes.html new file mode 100644 index 0000000000..0a4a491606 --- /dev/null +++ b/dom/security/test/csp/file_blob_data_schemes.html @@ -0,0 +1,49 @@ + + + + Bug 1086999 - Wildcard should not match blob:, data: + + + + + diff --git a/dom/security/test/csp/file_blob_top_nav_block_modals.html b/dom/security/test/csp/file_blob_top_nav_block_modals.html new file mode 100644 index 0000000000..545f6cffff --- /dev/null +++ b/dom/security/test/csp/file_blob_top_nav_block_modals.html @@ -0,0 +1,18 @@ + + + + + + + + + \ No newline at end of file diff --git a/dom/security/test/csp/file_blob_top_nav_block_modals.html^headers^ b/dom/security/test/csp/file_blob_top_nav_block_modals.html^headers^ new file mode 100644 index 0000000000..e2d945d556 --- /dev/null +++ b/dom/security/test/csp/file_blob_top_nav_block_modals.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: sandbox allow-scripts; \ No newline at end of file diff --git a/dom/security/test/csp/file_blob_uri_blocks_modals.html b/dom/security/test/csp/file_blob_uri_blocks_modals.html new file mode 100644 index 0000000000..caf2a5de41 --- /dev/null +++ b/dom/security/test/csp/file_blob_uri_blocks_modals.html @@ -0,0 +1,27 @@ + + + + + + + + + + + diff --git a/dom/security/test/csp/file_blob_uri_blocks_modals.html^headers^ b/dom/security/test/csp/file_blob_uri_blocks_modals.html^headers^ new file mode 100644 index 0000000000..e2d945d556 --- /dev/null +++ b/dom/security/test/csp/file_blob_uri_blocks_modals.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: sandbox allow-scripts; \ No newline at end of file diff --git a/dom/security/test/csp/file_block_all_mcb.sjs b/dom/security/test/csp/file_block_all_mcb.sjs new file mode 100644 index 0000000000..003c9df57c --- /dev/null +++ b/dom/security/test/csp/file_block_all_mcb.sjs @@ -0,0 +1,78 @@ +// custom *.sjs for Bug 1122236 +// CSP: 'block-all-mixed-content' + +const HEAD = + "" + + '' + + "Bug 1122236 - CSP: Implement block-all-mixed-content" + + ""; + +const CSP_ALLOW = + ''; + +const CSP_BLOCK = + ''; + +const BODY = + "" + + '' + + '" + + "" + + ""; + +// We have to use this special code fragment, in particular '?nocache' to trigger an +// actual network load rather than loading the image from the cache. +const BODY_CSPRO = + "" + + '' + + '" + + "" + + ""; + +function handleRequest(request, response) { + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + var queryString = request.queryString; + + if (queryString === "csp-block") { + response.write(HEAD + CSP_BLOCK + BODY); + return; + } + if (queryString === "csp-allow") { + response.write(HEAD + CSP_ALLOW + BODY); + return; + } + if (queryString === "no-csp") { + response.write(HEAD + BODY); + return; + } + if (queryString === "cspro-block") { + // CSP RO is not supported in meta tag, let's use the header + response.setHeader( + "Content-Security-Policy-Report-Only", + "block-all-mixed-content", + false + ); + response.write(HEAD + BODY_CSPRO); + return; + } + // we should never get here but just in case return something unexpected + response.write("do'h"); +} diff --git a/dom/security/test/csp/file_block_all_mixed_content_frame_navigation1.html b/dom/security/test/csp/file_block_all_mixed_content_frame_navigation1.html new file mode 100644 index 0000000000..fdc1ae87ac --- /dev/null +++ b/dom/security/test/csp/file_block_all_mixed_content_frame_navigation1.html @@ -0,0 +1,19 @@ + + + + + + Bug 1122236 - CSP: Implement block-all-mixed-content + + +user clicks and navigates from https://b.com to http://c.com + +foo + + + + + diff --git a/dom/security/test/csp/file_block_all_mixed_content_frame_navigation2.html b/dom/security/test/csp/file_block_all_mixed_content_frame_navigation2.html new file mode 100644 index 0000000000..4c4084e9ed --- /dev/null +++ b/dom/security/test/csp/file_block_all_mixed_content_frame_navigation2.html @@ -0,0 +1,15 @@ + + + + + Bug 1122236 - CSP: Implement block-all-mixed-content + + +http://c.com loaded, let's tell the parent + + + + + diff --git a/dom/security/test/csp/file_blocked_uri_in_violation_event_after_redirects.html b/dom/security/test/csp/file_blocked_uri_in_violation_event_after_redirects.html new file mode 100644 index 0000000000..74af0ff767 --- /dev/null +++ b/dom/security/test/csp/file_blocked_uri_in_violation_event_after_redirects.html @@ -0,0 +1,39 @@ + + + + Bug 1542194 - Check blockedURI in violation reports after redirects + + + + + + +
+ + + diff --git a/dom/security/test/csp/file_blocked_uri_in_violation_event_after_redirects.sjs b/dom/security/test/csp/file_blocked_uri_in_violation_event_after_redirects.sjs new file mode 100644 index 0000000000..ef397011c9 --- /dev/null +++ b/dom/security/test/csp/file_blocked_uri_in_violation_event_after_redirects.sjs @@ -0,0 +1,51 @@ +// Redirect server specifically for the needs of Bug 1542194 + +"use strict"; + +let REDIRECT_302_URI = + "http://test1.example.com/tests/dom/security/test/csp/file_blocked_uri_in_violation_event_after_redirects.sjs?test1b#ref1b"; + +let JS_REDIRECT = ` + + + + `; + +let LINK_CLICK_NAVIGATION = ` + + click me + + + `; + +function handleRequest(request, response) { + response.setHeader("Cache-Control", "no-cache", false); + + let query = request.queryString; + + // Test 1: 302 redirect + if (query === "test1a") { + var newLocation = REDIRECT_302_URI; + response.setStatusLine("1.1", 302, "Found"); + response.setHeader("Location", newLocation, false); + return; + } + + // Test 2: JS redirect + if (query === "test2a") { + response.setHeader("Content-Type", "text/html", false); + response.write(JS_REDIRECT); + return; + } + + // Test 3: Link navigation + if (query === "test3a") { + response.setHeader("Content-Type", "text/html", false); + response.write(LINK_CLICK_NAVIGATION); + } +} diff --git a/dom/security/test/csp/file_blocked_uri_redirect_frame_src.html b/dom/security/test/csp/file_blocked_uri_redirect_frame_src.html new file mode 100644 index 0000000000..c3af4d5a09 --- /dev/null +++ b/dom/security/test/csp/file_blocked_uri_redirect_frame_src.html @@ -0,0 +1,10 @@ + + + + Bug 1687342 - Check blocked-uri in csp-reports after frame redirect + + + Contents of the following iframe will be blocked
+ + + diff --git a/dom/security/test/csp/file_blocked_uri_redirect_frame_src.html^headers^ b/dom/security/test/csp/file_blocked_uri_redirect_frame_src.html^headers^ new file mode 100644 index 0000000000..b69131f8eb --- /dev/null +++ b/dom/security/test/csp/file_blocked_uri_redirect_frame_src.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: frame-src http://example.com; report-uri http://mochi.test:8888/foo.sjs; diff --git a/dom/security/test/csp/file_blocked_uri_redirect_frame_src_server.sjs b/dom/security/test/csp/file_blocked_uri_redirect_frame_src_server.sjs new file mode 100644 index 0000000000..9bf051f29b --- /dev/null +++ b/dom/security/test/csp/file_blocked_uri_redirect_frame_src_server.sjs @@ -0,0 +1,13 @@ +// Redirect server specifically for the needs of Bug 1687342 + +function handleRequest(request, response) { + response.setHeader("Cache-Control", "no-cache", false); + + let query = request.queryString; + if (query === "doredirect") { + var newLocation = + "http://test1.example.com/tests/dom/security/test/csp/file_blocked_uri_redirect_frame_src_server.sjs?query#ref2"; + response.setStatusLine("1.1", 302, "Found"); + response.setHeader("Location", newLocation, false); + } +} diff --git a/dom/security/test/csp/file_bug1229639.html b/dom/security/test/csp/file_bug1229639.html new file mode 100644 index 0000000000..1e6152ead0 --- /dev/null +++ b/dom/security/test/csp/file_bug1229639.html @@ -0,0 +1,7 @@ + + + + + + + diff --git a/dom/security/test/csp/file_bug1229639.html^headers^ b/dom/security/test/csp/file_bug1229639.html^headers^ new file mode 100644 index 0000000000..0177de7a38 --- /dev/null +++ b/dom/security/test/csp/file_bug1229639.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: "default-src 'self'; script-src http://mochi.test:8888/tests/dom/security/test/csp/%24.js \ No newline at end of file diff --git a/dom/security/test/csp/file_bug1312272.html b/dom/security/test/csp/file_bug1312272.html new file mode 100644 index 0000000000..18e0e5589e --- /dev/null +++ b/dom/security/test/csp/file_bug1312272.html @@ -0,0 +1,13 @@ + + + + + + marquee inline script tests for Bug 1312272 + + +bug 1312272 + + + diff --git a/dom/security/test/csp/file_bug1312272.html^headers^ b/dom/security/test/csp/file_bug1312272.html^headers^ new file mode 100644 index 0000000000..25a9483ea9 --- /dev/null +++ b/dom/security/test/csp/file_bug1312272.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: default-src *; script-src * 'unsafe-eval' diff --git a/dom/security/test/csp/file_bug1312272.js b/dom/security/test/csp/file_bug1312272.js new file mode 100644 index 0000000000..450013bec1 --- /dev/null +++ b/dom/security/test/csp/file_bug1312272.js @@ -0,0 +1,8 @@ +var m = document.getElementById("m"); +m.addEventListener("click", function () { + // this will trigger after onstart, obviously. + parent.postMessage("finish", "*"); +}); +console.log("finish-handler setup"); +m.click(); +console.log("clicked"); diff --git a/dom/security/test/csp/file_bug1452037.html b/dom/security/test/csp/file_bug1452037.html new file mode 100644 index 0000000000..0fb41d6654 --- /dev/null +++ b/dom/security/test/csp/file_bug1452037.html @@ -0,0 +1,9 @@ + + + + + + + Click here + + diff --git a/dom/security/test/csp/file_bug1505412.sjs b/dom/security/test/csp/file_bug1505412.sjs new file mode 100644 index 0000000000..e47bf2506a --- /dev/null +++ b/dom/security/test/csp/file_bug1505412.sjs @@ -0,0 +1,34 @@ +// https://bugzilla.mozilla.org/show_bug.cgi?id=650386 +// This SJS file serves file_redirect_content.html +// with a CSP that will trigger a violation and that will report it +// to file_redirect_report.sjs +// +// This handles 301, 302, 303 and 307 redirects. The HTTP status code +// returned/type of redirect to do comes from the query string +// parameter passed in from the test_bug650386_* files and then also +// uses that value in the report-uri parameter of the CSP +function handleRequest(request, response) { + response.setHeader("Cache-Control", "no-cache", false); + + // this gets used in the CSP as part of the report URI. + var redirect = request.queryString; + + if (!redirect) { + // if we somehow got some bogus redirect code here, + // do a 302 redirect to the same URL as the report URI + // redirects to - this will fail the test. + var loc = + "http://sub1.test1.example.org/tests/dom/security/test/csp/file_bug1505412.sjs?redirected"; + response.setStatusLine("1.1", 302, "Found"); + response.setHeader("Location", loc, false); + return; + } + + // response.setHeader("content-type", "text/application", false); + // the actual file content. + // this image load will (intentionally) fail due to the CSP policy of default-src: 'self' + // specified by the CSP string above. + var content = "info('Script Loaded')"; + + response.write(content); +} diff --git a/dom/security/test/csp/file_bug1505412_frame.html b/dom/security/test/csp/file_bug1505412_frame.html new file mode 100644 index 0000000000..b58af55849 --- /dev/null +++ b/dom/security/test/csp/file_bug1505412_frame.html @@ -0,0 +1,14 @@ + + + + + Bug 1505412 CSP-RO reports violations in inline-scripts with nonce + + + + + + + + + diff --git a/dom/security/test/csp/file_bug1505412_frame.html^headers^ b/dom/security/test/csp/file_bug1505412_frame.html^headers^ new file mode 100644 index 0000000000..e60b63c29c --- /dev/null +++ b/dom/security/test/csp/file_bug1505412_frame.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy-Report-Only: script-src 'nonce-foobar'; report-uri file_bug1505412_reporter.sjs diff --git a/dom/security/test/csp/file_bug1505412_reporter.sjs b/dom/security/test/csp/file_bug1505412_reporter.sjs new file mode 100644 index 0000000000..323a4edb1c --- /dev/null +++ b/dom/security/test/csp/file_bug1505412_reporter.sjs @@ -0,0 +1,18 @@ +function handleRequest(request, response) { + var receivedRequests = parseInt(getState("requests")); + if (isNaN(receivedRequests)) { + receivedRequests = 0; + } + if (request.queryString.includes("state")) { + response.write(receivedRequests); + return; + } + if (request.queryString.includes("flush")) { + setState("requests", "0"); + response.write("OK"); + return; + } + receivedRequests = receivedRequests + 1; + setState("requests", "" + receivedRequests); + response.write("OK"); +} diff --git a/dom/security/test/csp/file_bug1738418_child.html b/dom/security/test/csp/file_bug1738418_child.html new file mode 100644 index 0000000000..26e7f8f1f6 --- /dev/null +++ b/dom/security/test/csp/file_bug1738418_child.html @@ -0,0 +1,11 @@ + + + + + + diff --git a/dom/security/test/csp/file_bug1738418_parent.html b/dom/security/test/csp/file_bug1738418_parent.html new file mode 100644 index 0000000000..c8bdbb2c46 --- /dev/null +++ b/dom/security/test/csp/file_bug1738418_parent.html @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/dom/security/test/csp/file_bug1738418_parent.html^headers^ b/dom/security/test/csp/file_bug1738418_parent.html^headers^ new file mode 100644 index 0000000000..4705ce9ded --- /dev/null +++ b/dom/security/test/csp/file_bug1738418_parent.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: sandbox allow-scripts; diff --git a/dom/security/test/csp/file_bug1764343.html b/dom/security/test/csp/file_bug1764343.html new file mode 100644 index 0000000000..09781cce89 --- /dev/null +++ b/dom/security/test/csp/file_bug1764343.html @@ -0,0 +1,11 @@ + + + + + Bug 1764343 - CSP inheritance for same-origin iframes + + + + initial content + + diff --git a/dom/security/test/csp/file_bug1777572.html b/dom/security/test/csp/file_bug1777572.html new file mode 100644 index 0000000000..51f2a80d28 --- /dev/null +++ b/dom/security/test/csp/file_bug1777572.html @@ -0,0 +1,43 @@ + + + + + + + diff --git a/dom/security/test/csp/file_bug663567.xsl b/dom/security/test/csp/file_bug663567.xsl new file mode 100644 index 0000000000..b12b0d3b1d --- /dev/null +++ b/dom/security/test/csp/file_bug663567.xsl @@ -0,0 +1,27 @@ + + + + + + + +

this xml file should be formatted using an xsl file(lower iframe should contain xml dump)!

+ + + + + + + + + + + + + +
TitleArtistPrice
+ + +
+
+ diff --git a/dom/security/test/csp/file_bug663567_allows.xml b/dom/security/test/csp/file_bug663567_allows.xml new file mode 100644 index 0000000000..93d3451038 --- /dev/null +++ b/dom/security/test/csp/file_bug663567_allows.xml @@ -0,0 +1,28 @@ + + + + + Empire Burlesque + Bob Dylan + USA + Columbia + 10.90 + 1985 + + + Hide your heart + Bonnie Tyler + UK + CBS Records + 9.90 + 1988 + + + Greatest Hits + Dolly Parton + USA + RCA + 9.90 + 1982 + + diff --git a/dom/security/test/csp/file_bug663567_allows.xml^headers^ b/dom/security/test/csp/file_bug663567_allows.xml^headers^ new file mode 100644 index 0000000000..4c6fa3c26a --- /dev/null +++ b/dom/security/test/csp/file_bug663567_allows.xml^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: default-src 'self' diff --git a/dom/security/test/csp/file_bug663567_blocks.xml b/dom/security/test/csp/file_bug663567_blocks.xml new file mode 100644 index 0000000000..93d3451038 --- /dev/null +++ b/dom/security/test/csp/file_bug663567_blocks.xml @@ -0,0 +1,28 @@ + + + + + Empire Burlesque + Bob Dylan + USA + Columbia + 10.90 + 1985 + + + Hide your heart + Bonnie Tyler + UK + CBS Records + 9.90 + 1988 + + + Greatest Hits + Dolly Parton + USA + RCA + 9.90 + 1982 + + diff --git a/dom/security/test/csp/file_bug663567_blocks.xml^headers^ b/dom/security/test/csp/file_bug663567_blocks.xml^headers^ new file mode 100644 index 0000000000..baf7f3c6af --- /dev/null +++ b/dom/security/test/csp/file_bug663567_blocks.xml^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: default-src *.example.com diff --git a/dom/security/test/csp/file_bug802872.html b/dom/security/test/csp/file_bug802872.html new file mode 100644 index 0000000000..dae040376b --- /dev/null +++ b/dom/security/test/csp/file_bug802872.html @@ -0,0 +1,12 @@ + + + + Bug 802872 + + + + + + + + diff --git a/dom/security/test/csp/file_bug802872.html^headers^ b/dom/security/test/csp/file_bug802872.html^headers^ new file mode 100644 index 0000000000..4c6fa3c26a --- /dev/null +++ b/dom/security/test/csp/file_bug802872.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: default-src 'self' diff --git a/dom/security/test/csp/file_bug802872.js b/dom/security/test/csp/file_bug802872.js new file mode 100644 index 0000000000..042e190269 --- /dev/null +++ b/dom/security/test/csp/file_bug802872.js @@ -0,0 +1,47 @@ +/* + * The policy for this test is: + * Content-Security-Policy: default-src 'self' + */ + +function createAllowedEvent() { + /* + * Creates a new EventSource using 'http://mochi.test:8888'. Since all mochitests run on + * 'http://mochi.test', a default-src of 'self' allows this request. + */ + var src_event = new EventSource( + "http://mochi.test:8888/tests/dom/security/test/csp/file_bug802872.sjs" + ); + + src_event.onmessage = function (e) { + src_event.close(); + parent.dispatchEvent(new Event("allowedEventSrcCallbackOK")); + }; + + src_event.onerror = function (e) { + src_event.close(); + parent.dispatchEvent(new Event("allowedEventSrcCallbackFailed")); + }; +} + +function createBlockedEvent() { + /* + * creates a new EventSource using 'http://example.com'. This domain is not allowlisted by the + * CSP of this page, therefore the CSP blocks this request. + */ + var src_event = new EventSource( + "http://example.com/tests/dom/security/test/csp/file_bug802872.sjs" + ); + + src_event.onmessage = function (e) { + src_event.close(); + parent.dispatchEvent(new Event("blockedEventSrcCallbackOK")); + }; + + src_event.onerror = function (e) { + src_event.close(); + parent.dispatchEvent(new Event("blockedEventSrcCallbackFailed")); + }; +} + +addLoadEvent(createAllowedEvent); +addLoadEvent(createBlockedEvent); diff --git a/dom/security/test/csp/file_bug802872.sjs b/dom/security/test/csp/file_bug802872.sjs new file mode 100644 index 0000000000..6877bd5833 --- /dev/null +++ b/dom/security/test/csp/file_bug802872.sjs @@ -0,0 +1,6 @@ +function handleRequest(request, response) { + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/event-stream", false); + response.write("data: eventsource response from server!"); + response.write("\n\n"); +} diff --git a/dom/security/test/csp/file_bug836922_npolicies.html b/dom/security/test/csp/file_bug836922_npolicies.html new file mode 100644 index 0000000000..6a728813a7 --- /dev/null +++ b/dom/security/test/csp/file_bug836922_npolicies.html @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/dom/security/test/csp/file_bug836922_npolicies.html^headers^ b/dom/security/test/csp/file_bug836922_npolicies.html^headers^ new file mode 100644 index 0000000000..ec6ba8c4ae --- /dev/null +++ b/dom/security/test/csp/file_bug836922_npolicies.html^headers^ @@ -0,0 +1,2 @@ +content-security-policy: default-src 'self'; img-src 'none'; report-uri http://mochi.test:8888/tests/dom/security/test/csp/file_bug836922_npolicies_violation.sjs +content-security-policy-report-only: default-src *; img-src 'self'; script-src 'none'; report-uri http://mochi.test:8888/tests/dom/security/test/csp/file_bug836922_npolicies_ro_violation.sjs diff --git a/dom/security/test/csp/file_bug836922_npolicies_ro_violation.sjs b/dom/security/test/csp/file_bug836922_npolicies_ro_violation.sjs new file mode 100644 index 0000000000..0f5eb4b596 --- /dev/null +++ b/dom/security/test/csp/file_bug836922_npolicies_ro_violation.sjs @@ -0,0 +1,53 @@ +// SJS file that receives violation reports and then responds with nothing. + +const CC = Components.Constructor; +const BinaryInputStream = CC( + "@mozilla.org/binaryinputstream;1", + "nsIBinaryInputStream", + "setInputStream" +); + +const STATE_KEY = "bug836922_ro_violations"; + +function handleRequest(request, response) { + var query = {}; + request.queryString.split("&").forEach(function (val) { + var [name, value] = val.split("="); + query[name] = unescape(value); + }); + + if ("results" in query) { + // if asked for the received data, send it. + response.setHeader("Content-Type", "text/javascript", false); + if (getState(STATE_KEY)) { + response.write(getState(STATE_KEY)); + } else { + // no state has been recorded. + response.write(JSON.stringify({})); + } + } else if ("reset" in query) { + //clear state + setState(STATE_KEY, JSON.stringify(null)); + } else { + // ... otherwise, just respond "ok". + response.write("null"); + + var bodystream = new BinaryInputStream(request.bodyInputStream); + var avail; + var bytes = []; + while ((avail = bodystream.available()) > 0) { + Array.prototype.push.apply(bytes, bodystream.readByteArray(avail)); + } + + var data = String.fromCharCode.apply(null, bytes); + + // figure out which test was violating a policy + var testpat = new RegExp("testid=([a-z0-9_]+)"); + var testid = testpat.exec(data)[1]; + + // store the violation in the persistent state + var s = JSON.parse(getState(STATE_KEY) || "{}"); + s[testid] ? s[testid]++ : (s[testid] = 1); + setState(STATE_KEY, JSON.stringify(s)); + } +} diff --git a/dom/security/test/csp/file_bug836922_npolicies_violation.sjs b/dom/security/test/csp/file_bug836922_npolicies_violation.sjs new file mode 100644 index 0000000000..dec8b4f081 --- /dev/null +++ b/dom/security/test/csp/file_bug836922_npolicies_violation.sjs @@ -0,0 +1,64 @@ +// SJS file that receives violation reports and then responds with nothing. + +const CC = Components.Constructor; +const BinaryInputStream = CC( + "@mozilla.org/binaryinputstream;1", + "nsIBinaryInputStream", + "setInputStream" +); + +const STATE = "bug836922_violations"; + +function handleRequest(request, response) { + var query = {}; + request.queryString.split("&").forEach(function (val) { + var [name, value] = val.split("="); + query[name] = unescape(value); + }); + + if ("results" in query) { + // if asked for the received data, send it. + response.setHeader("Content-Type", "text/javascript", false); + if (getState(STATE)) { + response.write(getState(STATE)); + } else { + // no state has been recorded. + response.write(JSON.stringify({})); + } + } else if ("reset" in query) { + //clear state + setState(STATE, JSON.stringify(null)); + } else { + // ... otherwise, just respond "ok". + response.write("null"); + + var bodystream = new BinaryInputStream(request.bodyInputStream); + var avail; + var bytes = []; + while ((avail = bodystream.available()) > 0) { + Array.prototype.push.apply(bytes, bodystream.readByteArray(avail)); + } + + var data = String.fromCharCode.apply(null, bytes); + + // figure out which test was violating a policy + var testpat = new RegExp("testid=([a-z0-9_]+)"); + var testid = testpat.exec(data)[1]; + + // store the violation in the persistent state + var s = getState(STATE); + if (!s) { + s = "{}"; + } + s = JSON.parse(s); + if (!s) { + s = {}; + } + + if (!s[testid]) { + s[testid] = 0; + } + s[testid]++; + setState(STATE, JSON.stringify(s)); + } +} diff --git a/dom/security/test/csp/file_bug885433_allows.html b/dom/security/test/csp/file_bug885433_allows.html new file mode 100644 index 0000000000..c88981c4fe --- /dev/null +++ b/dom/security/test/csp/file_bug885433_allows.html @@ -0,0 +1,39 @@ + + + + +
    +
  1. Inline script allowed (this text should be green)
  2. +
  3. Eval script allowed (this text should be green)
  4. +
  5. Inline style allowed (this text should be green)
  6. +
+ + + + + + diff --git a/dom/security/test/csp/file_bug885433_allows.html^headers^ b/dom/security/test/csp/file_bug885433_allows.html^headers^ new file mode 100644 index 0000000000..767b9ca926 --- /dev/null +++ b/dom/security/test/csp/file_bug885433_allows.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: img-src 'self'; diff --git a/dom/security/test/csp/file_bug885433_blocks.html b/dom/security/test/csp/file_bug885433_blocks.html new file mode 100644 index 0000000000..b9a8aeb03b --- /dev/null +++ b/dom/security/test/csp/file_bug885433_blocks.html @@ -0,0 +1,38 @@ + + + + +
    +
  1. Inline script blocked (this text should be black)
  2. +
  3. Eval script blocked (this text should be black)
  4. +
  5. Inline style blocked (this text should be black)
  6. +
+ + + + + + diff --git a/dom/security/test/csp/file_bug885433_blocks.html^headers^ b/dom/security/test/csp/file_bug885433_blocks.html^headers^ new file mode 100644 index 0000000000..f82598b673 --- /dev/null +++ b/dom/security/test/csp/file_bug885433_blocks.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: default-src 'self'; diff --git a/dom/security/test/csp/file_bug886164.html b/dom/security/test/csp/file_bug886164.html new file mode 100644 index 0000000000..ec8c9e7e92 --- /dev/null +++ b/dom/security/test/csp/file_bug886164.html @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/dom/security/test/csp/file_bug886164.html^headers^ b/dom/security/test/csp/file_bug886164.html^headers^ new file mode 100644 index 0000000000..4c6fa3c26a --- /dev/null +++ b/dom/security/test/csp/file_bug886164.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: default-src 'self' diff --git a/dom/security/test/csp/file_bug886164_2.html b/dom/security/test/csp/file_bug886164_2.html new file mode 100644 index 0000000000..83d36c55ae --- /dev/null +++ b/dom/security/test/csp/file_bug886164_2.html @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/dom/security/test/csp/file_bug886164_2.html^headers^ b/dom/security/test/csp/file_bug886164_2.html^headers^ new file mode 100644 index 0000000000..4c6fa3c26a --- /dev/null +++ b/dom/security/test/csp/file_bug886164_2.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: default-src 'self' diff --git a/dom/security/test/csp/file_bug886164_3.html b/dom/security/test/csp/file_bug886164_3.html new file mode 100644 index 0000000000..8b4313000f --- /dev/null +++ b/dom/security/test/csp/file_bug886164_3.html @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/dom/security/test/csp/file_bug886164_3.html^headers^ b/dom/security/test/csp/file_bug886164_3.html^headers^ new file mode 100644 index 0000000000..6581fd425e --- /dev/null +++ b/dom/security/test/csp/file_bug886164_3.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: default-src 'none' diff --git a/dom/security/test/csp/file_bug886164_4.html b/dom/security/test/csp/file_bug886164_4.html new file mode 100644 index 0000000000..41137ea017 --- /dev/null +++ b/dom/security/test/csp/file_bug886164_4.html @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/dom/security/test/csp/file_bug886164_4.html^headers^ b/dom/security/test/csp/file_bug886164_4.html^headers^ new file mode 100644 index 0000000000..6581fd425e --- /dev/null +++ b/dom/security/test/csp/file_bug886164_4.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: default-src 'none' diff --git a/dom/security/test/csp/file_bug886164_5.html b/dom/security/test/csp/file_bug886164_5.html new file mode 100644 index 0000000000..82c10f20c0 --- /dev/null +++ b/dom/security/test/csp/file_bug886164_5.html @@ -0,0 +1,26 @@ + + + + + + + I am sandboxed but with only inline "allow-scripts" + + + + + + + + + + + diff --git a/dom/security/test/csp/file_bug886164_5.html^headers^ b/dom/security/test/csp/file_bug886164_5.html^headers^ new file mode 100644 index 0000000000..3abc190552 --- /dev/null +++ b/dom/security/test/csp/file_bug886164_5.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: default-src 'none' 'unsafe-inline'; diff --git a/dom/security/test/csp/file_bug886164_6.html b/dom/security/test/csp/file_bug886164_6.html new file mode 100644 index 0000000000..f6567b470e --- /dev/null +++ b/dom/security/test/csp/file_bug886164_6.html @@ -0,0 +1,35 @@ + + + + + + + + + + I am sandboxed but with "allow-scripts" + + + +
+ First name: + Last name: + +
+ + click me + + diff --git a/dom/security/test/csp/file_bug886164_6.html^headers^ b/dom/security/test/csp/file_bug886164_6.html^headers^ new file mode 100644 index 0000000000..6f9fc3f25d --- /dev/null +++ b/dom/security/test/csp/file_bug886164_6.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: default-src 'self' 'unsafe-inline'; diff --git a/dom/security/test/csp/file_bug888172.html b/dom/security/test/csp/file_bug888172.html new file mode 100644 index 0000000000..8c0fc46066 --- /dev/null +++ b/dom/security/test/csp/file_bug888172.html @@ -0,0 +1,29 @@ + + + +
    +
  1. Inline script (green if allowed, black if blocked)
  2. +
  3. Eval script (green if allowed, black if blocked)
  4. +
  5. Inline style (green if allowed, black if blocked)
  6. +
+ + + + + + diff --git a/dom/security/test/csp/file_bug888172.sjs b/dom/security/test/csp/file_bug888172.sjs new file mode 100644 index 0000000000..422162afc2 --- /dev/null +++ b/dom/security/test/csp/file_bug888172.sjs @@ -0,0 +1,49 @@ +// SJS file for CSP mochitests + +const { NetUtil } = ChromeUtils.importESModule( + "resource://gre/modules/NetUtil.sys.mjs" +); + +function loadHTMLFromFile(path) { + // Load the HTML to return in the response from file. + // Since it's relative to the cwd of the test runner, we start there and + // append to get to the actual path of the file. + var testHTMLFile = Cc["@mozilla.org/file/directory_service;1"] + .getService(Ci.nsIProperties) + .get("CurWorkD", Ci.nsIFile); + var dirs = path.split("/"); + for (var i = 0; i < dirs.length; i++) { + testHTMLFile.append(dirs[i]); + } + var testHTMLFileStream = Cc[ + "@mozilla.org/network/file-input-stream;1" + ].createInstance(Ci.nsIFileInputStream); + testHTMLFileStream.init(testHTMLFile, -1, 0, 0); + var testHTML = NetUtil.readInputStreamToString( + testHTMLFileStream, + testHTMLFileStream.available() + ); + return testHTML; +} + +function handleRequest(request, response) { + var query = {}; + request.queryString.split("&").forEach(function (val) { + var [name, value] = val.split("="); + query[name] = unescape(value); + }); + + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + // Deliver the CSP policy encoded in the URI + if (query.csp) { + response.setHeader("Content-Security-Policy", unescape(query.csp), false); + } + + // Send HTML to test allowed/blocked behaviors + response.setHeader("Content-Type", "text/html", false); + response.write( + loadHTMLFromFile("tests/dom/security/test/csp/file_bug888172.html") + ); +} diff --git a/dom/security/test/csp/file_bug909029_none.html b/dom/security/test/csp/file_bug909029_none.html new file mode 100644 index 0000000000..0d4934a4a3 --- /dev/null +++ b/dom/security/test/csp/file_bug909029_none.html @@ -0,0 +1,20 @@ + + + + + + + +

This should be green

+

This should be black

+ + + + + diff --git a/dom/security/test/csp/file_bug909029_none.html^headers^ b/dom/security/test/csp/file_bug909029_none.html^headers^ new file mode 100644 index 0000000000..ecb3458750 --- /dev/null +++ b/dom/security/test/csp/file_bug909029_none.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: default-src * ; style-src 'none' 'unsafe-inline'; diff --git a/dom/security/test/csp/file_bug909029_star.html b/dom/security/test/csp/file_bug909029_star.html new file mode 100644 index 0000000000..bcb907a965 --- /dev/null +++ b/dom/security/test/csp/file_bug909029_star.html @@ -0,0 +1,19 @@ + + + + + + +

This should be green

+

This should be black

+ + + + + diff --git a/dom/security/test/csp/file_bug909029_star.html^headers^ b/dom/security/test/csp/file_bug909029_star.html^headers^ new file mode 100644 index 0000000000..eccc1c0110 --- /dev/null +++ b/dom/security/test/csp/file_bug909029_star.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: default-src *; style-src * 'unsafe-inline'; diff --git a/dom/security/test/csp/file_bug910139.sjs b/dom/security/test/csp/file_bug910139.sjs new file mode 100644 index 0000000000..fb27f2e4a1 --- /dev/null +++ b/dom/security/test/csp/file_bug910139.sjs @@ -0,0 +1,56 @@ +// Server side js file for bug 910139, see file test_bug910139.html for details. + +const { NetUtil } = ChromeUtils.importESModule( + "resource://gre/modules/NetUtil.sys.mjs" +); + +function loadResponseFromFile(path) { + var testHTMLFile = Cc["@mozilla.org/file/directory_service;1"] + .getService(Ci.nsIProperties) + .get("CurWorkD", Ci.nsIFile); + var dirs = path.split("/"); + for (var i = 0; i < dirs.length; i++) { + testHTMLFile.append(dirs[i]); + } + var testHTMLFileStream = Cc[ + "@mozilla.org/network/file-input-stream;1" + ].createInstance(Ci.nsIFileInputStream); + testHTMLFileStream.init(testHTMLFile, -1, 0, 0); + var testHTML = NetUtil.readInputStreamToString( + testHTMLFileStream, + testHTMLFileStream.available() + ); + return testHTML; +} + +var policies = [ + "default-src 'self'; script-src 'self'", // CSP for checkAllowed + "default-src 'self'; script-src *.example.com", // CSP for checkBlocked +]; + +function getPolicy() { + var index; + // setState only accepts strings as arguments + if (!getState("counter")) { + index = 0; + setState("counter", index.toString()); + } else { + index = parseInt(getState("counter")); + ++index; + setState("counter", index.toString()); + } + return policies[index]; +} + +function handleRequest(request, response) { + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + // set the required CSP + response.setHeader("Content-Security-Policy", getPolicy(), false); + + // return the requested XML file. + response.write( + loadResponseFromFile("tests/dom/security/test/csp/file_bug910139.xml") + ); +} diff --git a/dom/security/test/csp/file_bug910139.xml b/dom/security/test/csp/file_bug910139.xml new file mode 100644 index 0000000000..29feba9418 --- /dev/null +++ b/dom/security/test/csp/file_bug910139.xml @@ -0,0 +1,28 @@ + + + + + Empire Burlesque + Bob Dylan + USA + Columbia + 10.90 + 1985 + + + Hide your heart + Bonnie Tyler + UK + CBS Records + 9.90 + 1988 + + + Greatest Hits + Dolly Parton + USA + RCA + 9.90 + 1982 + + diff --git a/dom/security/test/csp/file_bug910139.xsl b/dom/security/test/csp/file_bug910139.xsl new file mode 100644 index 0000000000..b99abca099 --- /dev/null +++ b/dom/security/test/csp/file_bug910139.xsl @@ -0,0 +1,27 @@ + + + + + + + +

this xml file should be formatted using an xsl file(lower iframe should contain xml dump)!

+ + + + + + + + + + + + + +
TitleArtistPrice
+ + +
+
+ diff --git a/dom/security/test/csp/file_bug941404.html b/dom/security/test/csp/file_bug941404.html new file mode 100644 index 0000000000..3a2e636e0b --- /dev/null +++ b/dom/security/test/csp/file_bug941404.html @@ -0,0 +1,27 @@ + + + + + + + + + + + + diff --git a/dom/security/test/csp/file_bug941404_xhr.html b/dom/security/test/csp/file_bug941404_xhr.html new file mode 100644 index 0000000000..22e176f208 --- /dev/null +++ b/dom/security/test/csp/file_bug941404_xhr.html @@ -0,0 +1,5 @@ + + + + + diff --git a/dom/security/test/csp/file_bug941404_xhr.html^headers^ b/dom/security/test/csp/file_bug941404_xhr.html^headers^ new file mode 100644 index 0000000000..1e5f70cc37 --- /dev/null +++ b/dom/security/test/csp/file_bug941404_xhr.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: default-src 'none' 'unsafe-inline' 'unsafe-eval' diff --git a/dom/security/test/csp/file_child-src_iframe.html b/dom/security/test/csp/file_child-src_iframe.html new file mode 100644 index 0000000000..18749011b9 --- /dev/null +++ b/dom/security/test/csp/file_child-src_iframe.html @@ -0,0 +1,61 @@ + + + + Bug 1045891 + + + + + + diff --git a/dom/security/test/csp/file_child-src_inner_frame.html b/dom/security/test/csp/file_child-src_inner_frame.html new file mode 100644 index 0000000000..f0c4e66fa0 --- /dev/null +++ b/dom/security/test/csp/file_child-src_inner_frame.html @@ -0,0 +1,21 @@ + + + + Bug 1045891 + + + + + + diff --git a/dom/security/test/csp/file_child-src_service_worker.html b/dom/security/test/csp/file_child-src_service_worker.html new file mode 100644 index 0000000000..b291a4a4e8 --- /dev/null +++ b/dom/security/test/csp/file_child-src_service_worker.html @@ -0,0 +1,30 @@ + + + + Bug 1045891 + + + + + diff --git a/dom/security/test/csp/file_child-src_service_worker.js b/dom/security/test/csp/file_child-src_service_worker.js new file mode 100644 index 0000000000..b8445fb175 --- /dev/null +++ b/dom/security/test/csp/file_child-src_service_worker.js @@ -0,0 +1,3 @@ +this.addEventListener("install", function (event) { + close(); +}); diff --git a/dom/security/test/csp/file_child-src_shared_worker-redirect.html b/dom/security/test/csp/file_child-src_shared_worker-redirect.html new file mode 100644 index 0000000000..313915302e --- /dev/null +++ b/dom/security/test/csp/file_child-src_shared_worker-redirect.html @@ -0,0 +1,47 @@ + + + + Bug 1045891 + + + + + diff --git a/dom/security/test/csp/file_child-src_shared_worker.html b/dom/security/test/csp/file_child-src_shared_worker.html new file mode 100644 index 0000000000..ce0c0261ed --- /dev/null +++ b/dom/security/test/csp/file_child-src_shared_worker.html @@ -0,0 +1,35 @@ + + + + Bug 1045891 + + + + + diff --git a/dom/security/test/csp/file_child-src_shared_worker.js b/dom/security/test/csp/file_child-src_shared_worker.js new file mode 100644 index 0000000000..dbcdf9c9d7 --- /dev/null +++ b/dom/security/test/csp/file_child-src_shared_worker.js @@ -0,0 +1,8 @@ +onconnect = function (e) { + var port = e.ports[0]; + port.addEventListener("message", function (e) { + port.postMessage("success"); + }); + + port.start(); +}; diff --git a/dom/security/test/csp/file_child-src_shared_worker_data.html b/dom/security/test/csp/file_child-src_shared_worker_data.html new file mode 100644 index 0000000000..a4befe4ca3 --- /dev/null +++ b/dom/security/test/csp/file_child-src_shared_worker_data.html @@ -0,0 +1,37 @@ + + + + + Bug 1045891 + + + + + diff --git a/dom/security/test/csp/file_child-src_worker-redirect.html b/dom/security/test/csp/file_child-src_worker-redirect.html new file mode 100644 index 0000000000..b0029935c2 --- /dev/null +++ b/dom/security/test/csp/file_child-src_worker-redirect.html @@ -0,0 +1,47 @@ + + + + Bug 1045891 + + + + + diff --git a/dom/security/test/csp/file_child-src_worker.html b/dom/security/test/csp/file_child-src_worker.html new file mode 100644 index 0000000000..a9fdbb3282 --- /dev/null +++ b/dom/security/test/csp/file_child-src_worker.html @@ -0,0 +1,34 @@ + + + + Bug 1045891 + + + + + diff --git a/dom/security/test/csp/file_child-src_worker.js b/dom/security/test/csp/file_child-src_worker.js new file mode 100644 index 0000000000..a6bb5e8044 --- /dev/null +++ b/dom/security/test/csp/file_child-src_worker.js @@ -0,0 +1,3 @@ +onmessage = function (e) { + postMessage("worker"); +}; diff --git a/dom/security/test/csp/file_child-src_worker_data.html b/dom/security/test/csp/file_child-src_worker_data.html new file mode 100644 index 0000000000..e9e22f01da --- /dev/null +++ b/dom/security/test/csp/file_child-src_worker_data.html @@ -0,0 +1,33 @@ + + + + Bug 1045891 + + + + + diff --git a/dom/security/test/csp/file_connect-src-fetch.html b/dom/security/test/csp/file_connect-src-fetch.html new file mode 100644 index 0000000000..ff9b2f740b --- /dev/null +++ b/dom/security/test/csp/file_connect-src-fetch.html @@ -0,0 +1,16 @@ + + + + Bug 1139667 - Test mapping of fetch() to connect-src + + + + + diff --git a/dom/security/test/csp/file_connect-src.html b/dom/security/test/csp/file_connect-src.html new file mode 100644 index 0000000000..17a940a0e0 --- /dev/null +++ b/dom/security/test/csp/file_connect-src.html @@ -0,0 +1,21 @@ + + + + Bug 1031530 - Test mapping of XMLHttpRequest to connect-src + + + + + diff --git a/dom/security/test/csp/file_csp_frame_ancestors_about_blank.html b/dom/security/test/csp/file_csp_frame_ancestors_about_blank.html new file mode 100644 index 0000000000..6ce361a438 --- /dev/null +++ b/dom/security/test/csp/file_csp_frame_ancestors_about_blank.html @@ -0,0 +1,9 @@ + + + + Helper file for Bug 1668071 - CSP frame-ancestors in about:blank + + + CSP frame-ancestors in about:blank + + diff --git a/dom/security/test/csp/file_csp_frame_ancestors_about_blank.html^headers^ b/dom/security/test/csp/file_csp_frame_ancestors_about_blank.html^headers^ new file mode 100644 index 0000000000..e5d129c3e8 --- /dev/null +++ b/dom/security/test/csp/file_csp_frame_ancestors_about_blank.html^headers^ @@ -0,0 +1,2 @@ +Cache-Control: no-cache +Content-Security-Policy: frame-ancestors http://mochi.test:8888 http://mochi.xorigin-test:8888 diff --git a/dom/security/test/csp/file_csp_meta_uir.html b/dom/security/test/csp/file_csp_meta_uir.html new file mode 100644 index 0000000000..dba1030975 --- /dev/null +++ b/dom/security/test/csp/file_csp_meta_uir.html @@ -0,0 +1,13 @@ + + + + + Hello World + + + + + + diff --git a/dom/security/test/csp/file_data-uri_blocked.html b/dom/security/test/csp/file_data-uri_blocked.html new file mode 100644 index 0000000000..59b7b25902 --- /dev/null +++ b/dom/security/test/csp/file_data-uri_blocked.html @@ -0,0 +1,15 @@ + + + + + + Test for Bug 587377 + + + + + + + diff --git a/dom/security/test/csp/file_data-uri_blocked.html^headers^ b/dom/security/test/csp/file_data-uri_blocked.html^headers^ new file mode 100644 index 0000000000..4248cca188 --- /dev/null +++ b/dom/security/test/csp/file_data-uri_blocked.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: default-src 'self' 'report-sample'; img-src 'none' 'report-sample' diff --git a/dom/security/test/csp/file_data_csp_inheritance.html b/dom/security/test/csp/file_data_csp_inheritance.html new file mode 100644 index 0000000000..4ae2fedc69 --- /dev/null +++ b/dom/security/test/csp/file_data_csp_inheritance.html @@ -0,0 +1,24 @@ + + + + Bug 1381761 - Treating 'data:' documents as unique, opaque origins should still inherit the CSP + + + + + + + + + + diff --git a/dom/security/test/csp/file_data_csp_merge.html b/dom/security/test/csp/file_data_csp_merge.html new file mode 100644 index 0000000000..88ae8febe5 --- /dev/null +++ b/dom/security/test/csp/file_data_csp_merge.html @@ -0,0 +1,26 @@ + + + + Bug 1386183 - Meta CSP on data: URI iframe should be merged with toplevel CSP + + + + + + + + + + diff --git a/dom/security/test/csp/file_data_doc_ignore_meta_csp.html b/dom/security/test/csp/file_data_doc_ignore_meta_csp.html new file mode 100644 index 0000000000..9d6e9834dd --- /dev/null +++ b/dom/security/test/csp/file_data_doc_ignore_meta_csp.html @@ -0,0 +1,22 @@ + + + + Bug 1382869: data document should ignore meta csp + + + + + + + diff --git a/dom/security/test/csp/file_doccomment_meta.html b/dom/security/test/csp/file_doccomment_meta.html new file mode 100644 index 0000000000..a0f36a4bfe --- /dev/null +++ b/dom/security/test/csp/file_doccomment_meta.html @@ -0,0 +1,28 @@ + + + + Bug 663570 - Test doc.write(meta csp) + + + + + + + --> + + + + + + + + + + + + + + + diff --git a/dom/security/test/csp/file_docwrite_meta.css b/dom/security/test/csp/file_docwrite_meta.css new file mode 100644 index 0000000000..de725038b6 --- /dev/null +++ b/dom/security/test/csp/file_docwrite_meta.css @@ -0,0 +1,3 @@ +body { + background-color: rgb(255, 0, 0); +} diff --git a/dom/security/test/csp/file_docwrite_meta.html b/dom/security/test/csp/file_docwrite_meta.html new file mode 100644 index 0000000000..292de3bec5 --- /dev/null +++ b/dom/security/test/csp/file_docwrite_meta.html @@ -0,0 +1,26 @@ + + + + Bug 663570 - Test doc.write(meta csp) + + + + + + + + + + + + + + + + + + + diff --git a/dom/security/test/csp/file_docwrite_meta.js b/dom/security/test/csp/file_docwrite_meta.js new file mode 100644 index 0000000000..722adc235e --- /dev/null +++ b/dom/security/test/csp/file_docwrite_meta.js @@ -0,0 +1,3 @@ +// set a variable on the document which we can check to verify +// whether the external script was loaded or blocked +document.myMetaCSPScript = "external-JS-loaded"; diff --git a/dom/security/test/csp/file_dual_header_testserver.sjs b/dom/security/test/csp/file_dual_header_testserver.sjs new file mode 100644 index 0000000000..0efe186d57 --- /dev/null +++ b/dom/security/test/csp/file_dual_header_testserver.sjs @@ -0,0 +1,45 @@ +/* + * Custom sjs file serving a test page using *two* CSP policies. + * See Bug 1036399 - Multiple CSP policies should be combined towards an intersection + */ + +const TIGHT_POLICY = "default-src 'self'"; +const LOOSE_POLICY = "default-src 'self' 'unsafe-inline'"; + +function handleRequest(request, response) { + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + var csp = ""; + // deliver *TWO* comma separated policies which is in fact the same as serving + // to separate CSP headers (AppendPolicy is called twice). + if (request.queryString == "tight") { + // script execution will be *blocked* + csp = TIGHT_POLICY + ", " + LOOSE_POLICY; + } else { + // script execution will be *allowed* + csp = LOOSE_POLICY + ", " + LOOSE_POLICY; + } + response.setHeader("Content-Security-Policy", csp, false); + + // Send HTML to test allowed/blocked behaviors + response.setHeader("Content-Type", "text/html", false); + + // generate an html file that contains a div container which is updated + // in case the inline script is *not* blocked by CSP. + var html = + "" + + "" + + "" + + "Testpage for Bug 1036399" + + "" + + "" + + "
blocked
" + + "" + + "" + + ""; + + response.write(html); +} diff --git a/dom/security/test/csp/file_dummy_pixel.png b/dom/security/test/csp/file_dummy_pixel.png new file mode 100644 index 0000000000..52c591798e Binary files /dev/null and b/dom/security/test/csp/file_dummy_pixel.png differ diff --git a/dom/security/test/csp/file_empty_directive.html b/dom/security/test/csp/file_empty_directive.html new file mode 100644 index 0000000000..16196bb19f --- /dev/null +++ b/dom/security/test/csp/file_empty_directive.html @@ -0,0 +1,11 @@ + + + + + Bug 587377 - CSP keywords "'self'" and "'none'" are easy to confuse with host names "self" and "none" + + + + + diff --git a/dom/security/test/csp/file_empty_directive.html^headers^ b/dom/security/test/csp/file_empty_directive.html^headers^ new file mode 100644 index 0000000000..50dbe57bb9 --- /dev/null +++ b/dom/security/test/csp/file_empty_directive.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: ; diff --git a/dom/security/test/csp/file_evalscript_main.html b/dom/security/test/csp/file_evalscript_main.html new file mode 100644 index 0000000000..e83c1d9ed7 --- /dev/null +++ b/dom/security/test/csp/file_evalscript_main.html @@ -0,0 +1,12 @@ + + + CSP eval script tests + + + + + Foo. + + + diff --git a/dom/security/test/csp/file_evalscript_main.html^headers^ b/dom/security/test/csp/file_evalscript_main.html^headers^ new file mode 100644 index 0000000000..b91ba384d9 --- /dev/null +++ b/dom/security/test/csp/file_evalscript_main.html^headers^ @@ -0,0 +1,2 @@ +Cache-Control: no-cache +Content-Security-Policy: default-src 'self' diff --git a/dom/security/test/csp/file_evalscript_main.js b/dom/security/test/csp/file_evalscript_main.js new file mode 100644 index 0000000000..127f5d8152 --- /dev/null +++ b/dom/security/test/csp/file_evalscript_main.js @@ -0,0 +1,243 @@ +/* eslint-disable no-eval */ +// some javascript for the CSP eval() tests + +function logResult(str, passed) { + var elt = document.createElement("div"); + var color = passed ? "#cfc;" : "#fcc"; + elt.setAttribute( + "style", + "background-color:" + + color + + "; width:100%; border:1px solid black; padding:3px; margin:4px;" + ); + elt.innerHTML = str; + document.body.appendChild(elt); +} + +window._testResults = {}; + +// check values for return values from blocked timeout or intervals +var verifyZeroRetVal = (function (window) { + return function (val, details) { + logResult( + (val === 0 ? "PASS: " : "FAIL: ") + + "Blocked interval/timeout should have zero return value; " + + details, + val === 0 + ); + window.parent.verifyZeroRetVal(val, details); + }; +})(window); + +// callback for when stuff is allowed by CSP +var onevalexecuted = (function (window) { + return function (shouldrun, what, data) { + window._testResults[what] = "ran"; + window.parent.scriptRan(shouldrun, what, data); + logResult( + (shouldrun ? "PASS: " : "FAIL: ") + what + " : " + data, + shouldrun + ); + }; +})(window); + +// callback for when stuff is blocked +var onevalblocked = (function (window) { + return function (shouldrun, what, data) { + window._testResults[what] = "blocked"; + window.parent.scriptBlocked(shouldrun, what, data); + logResult( + (shouldrun ? "FAIL: " : "PASS: ") + what + " : " + data, + !shouldrun + ); + }; +})(window); + +// Defer until document is loaded so that we can write the pretty result boxes +// out. +addEventListener( + "load", + function () { + // setTimeout(String) test -- mutate something in the window._testResults + // obj, then check it. + { + var str_setTimeoutWithStringRan = + 'onevalexecuted(false, "setTimeout(String)", "setTimeout with a string was enabled.");'; + function fcn_setTimeoutWithStringCheck() { + if (this._testResults["setTimeout(String)"] !== "ran") { + onevalblocked( + false, + "setTimeout(String)", + "setTimeout with a string was blocked" + ); + } + } + setTimeout(fcn_setTimeoutWithStringCheck.bind(window), 10); + // eslint-disable-next-line no-implied-eval + var res = setTimeout(str_setTimeoutWithStringRan, 10); + verifyZeroRetVal(res, "setTimeout(String)"); + } + + // setInterval(String) test -- mutate something in the window._testResults + // obj, then check it. + { + var str_setIntervalWithStringRan = + 'onevalexecuted(false, "setInterval(String)", "setInterval with a string was enabled.");'; + function fcn_setIntervalWithStringCheck() { + if (this._testResults["setInterval(String)"] !== "ran") { + onevalblocked( + false, + "setInterval(String)", + "setInterval with a string was blocked" + ); + } + } + setTimeout(fcn_setIntervalWithStringCheck.bind(window), 10); + // eslint-disable-next-line no-implied-eval + var res = setInterval(str_setIntervalWithStringRan, 10); + verifyZeroRetVal(res, "setInterval(String)"); + + // emergency cleanup, just in case. + if (res != 0) { + setTimeout(function () { + clearInterval(res); + }, 15); + } + } + + // setTimeout(function) test -- mutate something in the window._testResults + // obj, then check it. + { + function fcn_setTimeoutWithFunctionRan() { + onevalexecuted( + true, + "setTimeout(function)", + "setTimeout with a function was enabled." + ); + } + function fcn_setTimeoutWithFunctionCheck() { + if (this._testResults["setTimeout(function)"] !== "ran") { + onevalblocked( + true, + "setTimeout(function)", + "setTimeout with a function was blocked" + ); + } + } + setTimeout(fcn_setTimeoutWithFunctionRan.bind(window), 10); + setTimeout(fcn_setTimeoutWithFunctionCheck.bind(window), 10); + } + + // eval() test -- should throw exception as per spec + try { + eval('onevalexecuted(false, "eval(String)", "eval() was enabled.");'); + } catch (e) { + onevalblocked(false, "eval(String)", "eval() was blocked"); + } + + // eval(foo,bar) test -- should throw exception as per spec + try { + eval( + 'onevalexecuted(false, "eval(String,scope)", "eval() was enabled.");', + 1 + ); + } catch (e) { + onevalblocked( + false, + "eval(String,object)", + "eval() with scope was blocked" + ); + } + + // [foo,bar].sort(eval) test -- should throw exception as per spec + try { + [ + 'onevalexecuted(false, "[String, obj].sort(eval)", "eval() was enabled.");', + 1, + ].sort(eval); + } catch (e) { + onevalblocked( + false, + "[String, obj].sort(eval)", + "eval() with scope via sort was blocked" + ); + } + + // [].sort.call([foo,bar], eval) test -- should throw exception as per spec + try { + [].sort.call( + [ + 'onevalexecuted(false, "[String, obj].sort(eval)", "eval() was enabled.");', + 1, + ], + eval + ); + } catch (e) { + onevalblocked( + false, + "[].sort.call([String, obj], eval)", + "eval() with scope via sort/call was blocked" + ); + } + + // new Function() test -- should throw exception as per spec + try { + var fcn = new Function( + 'onevalexecuted(false, "new Function(String)", "new Function(String) was enabled.");' + ); + fcn(); + } catch (e) { + onevalblocked( + false, + "new Function(String)", + "new Function(String) was blocked." + ); + } + + // ShadowRealm.prototype.evaluate -- should throw exception as per spec. + try { + var sr = new ShadowRealm(); + sr.evaluate("var x = 10"); + onevalexecuted( + false, + "ShadowRealm.prototype.evaluate(String)", + "ShadowRealm.prototype.evaluate(String) was enabled." + ); + } catch (e) { + onevalblocked( + false, + "ShadowRealm.prototype.evaluate(String)", + "ShadowRealm.prototype.evaluate(String) was blocked." + ); + } + + // setTimeout(eval, 0, str) + { + // error is not catchable here, instead, we're going to side-effect + // 'worked'. + var worked = false; + + setTimeout(eval, 0, "worked = true"); + setTimeout( + function (worked) { + if (worked) { + onevalexecuted( + false, + "setTimeout(eval, 0, str)", + "setTimeout(eval, 0, string) was enabled." + ); + } else { + onevalblocked( + false, + "setTimeout(eval, 0, str)", + "setTimeout(eval, 0, str) was blocked." + ); + } + }, + 0, + worked + ); + } + }, + false +); diff --git a/dom/security/test/csp/file_evalscript_main_allowed.html b/dom/security/test/csp/file_evalscript_main_allowed.html new file mode 100644 index 0000000000..274972d9bd --- /dev/null +++ b/dom/security/test/csp/file_evalscript_main_allowed.html @@ -0,0 +1,12 @@ + + + CSP eval script tests + + + + + Foo. + + + diff --git a/dom/security/test/csp/file_evalscript_main_allowed.html^headers^ b/dom/security/test/csp/file_evalscript_main_allowed.html^headers^ new file mode 100644 index 0000000000..0cb5288bec --- /dev/null +++ b/dom/security/test/csp/file_evalscript_main_allowed.html^headers^ @@ -0,0 +1,2 @@ +Cache-Control: no-cache +Content-Security-Policy: default-src 'self' ; script-src 'self' 'unsafe-eval' diff --git a/dom/security/test/csp/file_evalscript_main_allowed.js b/dom/security/test/csp/file_evalscript_main_allowed.js new file mode 100644 index 0000000000..6b014c339e --- /dev/null +++ b/dom/security/test/csp/file_evalscript_main_allowed.js @@ -0,0 +1,195 @@ +/* eslint-disable no-eval */ +// some javascript for the CSP eval() tests +// all of these evals should succeed, as the document loading this script +// has script-src 'self' 'unsafe-eval' + +function logResult(str, passed) { + var elt = document.createElement("div"); + var color = passed ? "#cfc;" : "#fcc"; + elt.setAttribute( + "style", + "background-color:" + + color + + "; width:100%; border:1px solid black; padding:3px; margin:4px;" + ); + elt.innerHTML = str; + document.body.appendChild(elt); +} + +// callback for when stuff is allowed by CSP +var onevalexecuted = (function (window) { + return function (shouldrun, what, data) { + window.parent.scriptRan(shouldrun, what, data); + logResult( + (shouldrun ? "PASS: " : "FAIL: ") + what + " : " + data, + shouldrun + ); + }; +})(window); + +// callback for when stuff is blocked +var onevalblocked = (function (window) { + return function (shouldrun, what, data) { + window.parent.scriptBlocked(shouldrun, what, data); + logResult( + (shouldrun ? "FAIL: " : "PASS: ") + what + " : " + data, + !shouldrun + ); + }; +})(window); + +// Defer until document is loaded so that we can write the pretty result boxes +// out. +addEventListener( + "load", + function () { + // setTimeout(String) test -- should pass + try { + // eslint-disable-next-line no-implied-eval + setTimeout( + 'onevalexecuted(true, "setTimeout(String)", "setTimeout with a string was enabled.");', + 10 + ); + } catch (e) { + onevalblocked( + true, + "setTimeout(String)", + "setTimeout with a string was blocked" + ); + } + + // setTimeout(function) test -- should pass + try { + setTimeout(function () { + onevalexecuted( + true, + "setTimeout(function)", + "setTimeout with a function was enabled." + ); + }, 10); + } catch (e) { + onevalblocked( + true, + "setTimeout(function)", + "setTimeout with a function was blocked" + ); + } + + // eval() test + try { + eval('onevalexecuted(true, "eval(String)", "eval() was enabled.");'); + } catch (e) { + onevalblocked(true, "eval(String)", "eval() was blocked"); + } + + // eval(foo,bar) test + try { + eval( + 'onevalexecuted(true, "eval(String,scope)", "eval() was enabled.");', + 1 + ); + } catch (e) { + onevalblocked( + true, + "eval(String,object)", + "eval() with scope was blocked" + ); + } + + // [foo,bar].sort(eval) test + try { + [ + 'onevalexecuted(true, "[String, obj].sort(eval)", "eval() was enabled.");', + 1, + ].sort(eval); + } catch (e) { + onevalblocked( + true, + "[String, obj].sort(eval)", + "eval() with scope via sort was blocked" + ); + } + + // [].sort.call([foo,bar], eval) test + try { + [].sort.call( + [ + 'onevalexecuted(true, "[String, obj].sort(eval)", "eval() was enabled.");', + 1, + ], + eval + ); + } catch (e) { + onevalblocked( + true, + "[].sort.call([String, obj], eval)", + "eval() with scope via sort/call was blocked" + ); + } + + // new Function() test + try { + var fcn = new Function( + 'onevalexecuted(true, "new Function(String)", "new Function(String) was enabled.");' + ); + fcn(); + } catch (e) { + onevalblocked( + true, + "new Function(String)", + "new Function(String) was blocked." + ); + } + + // ShadowRealm.prototype.evaluate + try { + var sr = new ShadowRealm(); + sr.evaluate("var x = 10"); + onevalexecuted( + true, + "ShadowRealm.prototype.evaluate(String)", + "ShadowRealm.prototype.evaluate(String) was enabled." + ); + } catch (e) { + onevalblocked( + true, + "ShadowRealm.prototype.evaluate(String)", + "ShadowRealm.prototype.evaluate(String) was blocked." + ); + } + + function checkResult() { + //alert(bar); + if (bar) { + onevalexecuted( + true, + "setTimeout(eval, 0, str)", + "setTimeout(eval, 0, string) was enabled." + ); + } else { + onevalblocked( + true, + "setTimeout(eval, 0, str)", + "setTimeout(eval, 0, str) was blocked." + ); + } + } + + var bar = false; + + function foo() { + bar = true; + } + + window.foo = foo; + + // setTimeout(eval, 0, str) + + // error is not catchable here + + setTimeout(eval, 0, "window.foo();"); + + setTimeout(checkResult.bind(this), 0); + }, + false +); diff --git a/dom/security/test/csp/file_fontloader.sjs b/dom/security/test/csp/file_fontloader.sjs new file mode 100644 index 0000000000..b9b5e602fe --- /dev/null +++ b/dom/security/test/csp/file_fontloader.sjs @@ -0,0 +1,57 @@ +// custom *.sjs for Bug 1195172 +// CSP: 'block-all-mixed-content' + +const PRE_HEAD = + "" + + '' + + "Bug 1195172 - CSP should block font from cache"; + +const CSP_BLOCK = + ''; + +const CSP_ALLOW = + ''; + +const CSS = + ""; + +const POST_HEAD_AND_BODY = + "" + + "" + + "
Just testing the font
" + + "" + + ""; + +function handleRequest(request, response) { + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + var queryString = request.queryString; + + if (queryString == "baseline") { + response.write(PRE_HEAD + POST_HEAD_AND_BODY); + return; + } + if (queryString == "no-csp") { + response.write(PRE_HEAD + CSS + POST_HEAD_AND_BODY); + return; + } + if (queryString == "csp-block") { + response.write(PRE_HEAD + CSP_BLOCK + CSS + POST_HEAD_AND_BODY); + return; + } + if (queryString == "csp-allow") { + response.write(PRE_HEAD + CSP_ALLOW + CSS + POST_HEAD_AND_BODY); + return; + } + // we should never get here, but just in case return something unexpected + response.write("do'h"); +} diff --git a/dom/security/test/csp/file_fontloader.woff b/dom/security/test/csp/file_fontloader.woff new file mode 100644 index 0000000000..fbf7390d59 Binary files /dev/null and b/dom/security/test/csp/file_fontloader.woff differ diff --git a/dom/security/test/csp/file_form-action.html b/dom/security/test/csp/file_form-action.html new file mode 100644 index 0000000000..cfff156bae --- /dev/null +++ b/dom/security/test/csp/file_form-action.html @@ -0,0 +1,15 @@ + + + + Bug 529697 - Test mapping of form submission to form-action + + +
+ +
+ + + diff --git a/dom/security/test/csp/file_form_action_server.sjs b/dom/security/test/csp/file_form_action_server.sjs new file mode 100644 index 0000000000..0c79736d47 --- /dev/null +++ b/dom/security/test/csp/file_form_action_server.sjs @@ -0,0 +1,32 @@ +// Custom *.sjs file specifically for the needs of Bug 1251043 + +const FRAME = ` + + + + Bug 1251043 - Test form-action blocks URL + + + + CONTROL-TEXT +
+ +
+ + `; + +function handleRequest(request, response) { + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + // PART 1: Return a frame including the FORM and the CSP + if (request.queryString === "loadframe") { + response.write(FRAME); + return; + } + + // PART 2: We should never get here because the form + // should not be submitted. Just in case; return + // something unexpected so the test fails! + response.write("do'h"); +} diff --git a/dom/security/test/csp/file_frame_ancestors_ro.html b/dom/security/test/csp/file_frame_ancestors_ro.html new file mode 100644 index 0000000000..ff5ae9cf9f --- /dev/null +++ b/dom/security/test/csp/file_frame_ancestors_ro.html @@ -0,0 +1 @@ +Child Document diff --git a/dom/security/test/csp/file_frame_ancestors_ro.html^headers^ b/dom/security/test/csp/file_frame_ancestors_ro.html^headers^ new file mode 100644 index 0000000000..d018af3a96 --- /dev/null +++ b/dom/security/test/csp/file_frame_ancestors_ro.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy-Report-Only: frame-ancestors 'none'; report-uri http://mochi.test:8888/foo.sjs diff --git a/dom/security/test/csp/file_frame_src.js b/dom/security/test/csp/file_frame_src.js new file mode 100644 index 0000000000..d30bc0ec62 --- /dev/null +++ b/dom/security/test/csp/file_frame_src.js @@ -0,0 +1,20 @@ +let testframe = document.getElementById("testframe"); +testframe.onload = function () { + parent.postMessage( + { + result: "frame-allowed", + href: document.location.href, + }, + "*" + ); +}; +testframe.onerror = function () { + parent.postMessage( + { + result: "frame-blocked", + href: document.location.href, + }, + "*" + ); +}; +testframe.src = "file_frame_src_inner.html"; diff --git a/dom/security/test/csp/file_frame_src_child_governs.html b/dom/security/test/csp/file_frame_src_child_governs.html new file mode 100644 index 0000000000..a51cb75be2 --- /dev/null +++ b/dom/security/test/csp/file_frame_src_child_governs.html @@ -0,0 +1,10 @@ + + + + "; + + + + + + diff --git a/dom/security/test/csp/file_frame_src_frame_governs.html b/dom/security/test/csp/file_frame_src_frame_governs.html new file mode 100644 index 0000000000..2c5d5857f2 --- /dev/null +++ b/dom/security/test/csp/file_frame_src_frame_governs.html @@ -0,0 +1,10 @@ + + + + "; + + + + + + diff --git a/dom/security/test/csp/file_frame_src_inner.html b/dom/security/test/csp/file_frame_src_inner.html new file mode 100644 index 0000000000..4a2fc6095a --- /dev/null +++ b/dom/security/test/csp/file_frame_src_inner.html @@ -0,0 +1,5 @@ + + +dummy iframe + + diff --git a/dom/security/test/csp/file_frameancestors.sjs b/dom/security/test/csp/file_frameancestors.sjs new file mode 100644 index 0000000000..25d4b3fe08 --- /dev/null +++ b/dom/security/test/csp/file_frameancestors.sjs @@ -0,0 +1,69 @@ +// SJS file for CSP frame ancestor mochitests +function handleRequest(request, response) { + var query = {}; + request.queryString.split("&").forEach(function (val) { + var [name, value] = val.split("="); + query[name] = unescape(value); + }); + + var isPreflight = request.method == "OPTIONS"; + + //avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + // grab the desired policy from the query, and then serve a page + if (query.csp) { + response.setHeader("Content-Security-Policy", unescape(query.csp), false); + } + if (query.scriptedreport) { + // spit back a script that records that the page loaded + response.setHeader("Content-Type", "text/javascript", false); + if (query.double) { + response.write( + 'window.parent.parent.parent.postMessage({call: "frameLoaded", testname: "' + + query.scriptedreport + + '", uri: "window.location.toString()"}, "*");' + ); + } else { + response.write( + 'window.parent.parent.postMessage({call: "frameLoaded", testname: "' + + query.scriptedreport + + '", uri: "window.location.toString()"}, "*");' + ); + } + } else if (query.internalframe) { + // spit back an internal iframe (one that might be blocked) + response.setHeader("Content-Type", "text/html", false); + response.write(""); + if (query.double) { + response.write( + '' + ); + } else { + response.write( + '' + ); + } + response.write(""); + response.write(unescape(query.internalframe)); + response.write(""); + } else if (query.externalframe) { + // spit back an internal iframe (one that won't be blocked, and probably + // has no CSP) + response.setHeader("Content-Type", "text/html", false); + response.write(""); + response.write(""); + response.write(unescape(query.externalframe)); + response.write(""); + } else { + // default case: error. + response.setHeader("Content-Type", "text/html", false); + response.write(""); + response.write("ERROR: not sure what to serve."); + response.write(""); + } +} diff --git a/dom/security/test/csp/file_frameancestors_main.html b/dom/security/test/csp/file_frameancestors_main.html new file mode 100644 index 0000000000..97f9cb9ac5 --- /dev/null +++ b/dom/security/test/csp/file_frameancestors_main.html @@ -0,0 +1,44 @@ + + + CSP frame ancestors tests + + + + + + + + + aa_allow: /* innermost frame allows a */
+
+ + aa_block: /* innermost frame denies a */
+
+ + ab_allow: /* innermost frame allows a */
+
+ + ab_block: /* innermost frame denies a */
+
+ + aba_allow: /* innermost frame allows b,a */
+
+ + aba_block: /* innermost frame denies b */
+
+ + aba2_block: /* innermost frame denies a */
+
+ + abb_allow: /* innermost frame allows b,a */
+
+ + abb_block: /* innermost frame denies b */
+
+ + abb2_block: /* innermost frame denies a */
+
+ + + + diff --git a/dom/security/test/csp/file_frameancestors_main.js b/dom/security/test/csp/file_frameancestors_main.js new file mode 100644 index 0000000000..2c5caf739f --- /dev/null +++ b/dom/security/test/csp/file_frameancestors_main.js @@ -0,0 +1,134 @@ +// Script to populate the test frames in the frame ancestors mochitest. +// +function setupFrames() { + var $ = function (v) { + return document.getElementById(v); + }; + var base = { + self: "/tests/dom/security/test/csp/file_frameancestors.sjs", + a: "http://mochi.test:8888/tests/dom/security/test/csp/file_frameancestors.sjs", + b: "http://example.com/tests/dom/security/test/csp/file_frameancestors.sjs", + }; + + // In both cases (base.a, base.b) the path starts with /tests/. Let's make sure this + // path within the CSP policy is completely ignored when enforcing frame ancestors. + // To test this behavior we use /foo/ and /bar/ as dummy values for the path. + var host = { + a: "http://mochi.test:8888/foo/", + b: "http://example.com:80/bar/", + }; + + var innerframeuri = null; + var elt = null; + + elt = $("aa_allow"); + elt.src = + base.a + + "?testid=aa_allow&internalframe=aa_a&csp=" + + escape( + "default-src 'none'; frame-ancestors " + host.a + "; script-src 'self'" + ); + + elt = $("aa_block"); + elt.src = + base.a + + "?testid=aa_block&internalframe=aa_b&csp=" + + escape("default-src 'none'; frame-ancestors 'none'; script-src 'self'"); + + elt = $("ab_allow"); + elt.src = + base.b + + "?testid=ab_allow&internalframe=ab_a&csp=" + + escape( + "default-src 'none'; frame-ancestors " + host.a + "; script-src 'self'" + ); + + elt = $("ab_block"); + elt.src = + base.b + + "?testid=ab_block&internalframe=ab_b&csp=" + + escape("default-src 'none'; frame-ancestors 'none'; script-src 'self'"); + + /* .... two-level framing */ + elt = $("aba_allow"); + innerframeuri = + base.a + + "?testid=aba_allow&double=1&internalframe=aba_a&csp=" + + escape( + "default-src 'none'; frame-ancestors " + + host.a + + " " + + host.b + + "; script-src 'self'" + ); + elt.src = + base.b + + "?externalframe=" + + escape(''); + + elt = $("aba_block"); + innerframeuri = + base.a + + "?testid=aba_allow&double=1&internalframe=aba_b&csp=" + + escape( + "default-src 'none'; frame-ancestors " + host.a + "; script-src 'self'" + ); + elt.src = + base.b + + "?externalframe=" + + escape(''); + + elt = $("aba2_block"); + innerframeuri = + base.a + + "?testid=aba_allow&double=1&internalframe=aba2_b&csp=" + + escape( + "default-src 'none'; frame-ancestors " + host.b + "; script-src 'self'" + ); + elt.src = + base.b + + "?externalframe=" + + escape(''); + + elt = $("abb_allow"); + innerframeuri = + base.b + + "?testid=abb_allow&double=1&internalframe=abb_a&csp=" + + escape( + "default-src 'none'; frame-ancestors " + + host.a + + " " + + host.b + + "; script-src 'self'" + ); + elt.src = + base.b + + "?externalframe=" + + escape(''); + + elt = $("abb_block"); + innerframeuri = + base.b + + "?testid=abb_allow&double=1&internalframe=abb_b&csp=" + + escape( + "default-src 'none'; frame-ancestors " + host.a + "; script-src 'self'" + ); + elt.src = + base.b + + "?externalframe=" + + escape(''); + + elt = $("abb2_block"); + innerframeuri = + base.b + + "?testid=abb_allow&double=1&internalframe=abb2_b&csp=" + + escape( + "default-src 'none'; frame-ancestors " + host.b + "; script-src 'self'" + ); + elt.src = + base.b + + "?externalframe=" + + escape(''); +} + +window.addEventListener("load", setupFrames); diff --git a/dom/security/test/csp/file_frameancestors_userpass.html b/dom/security/test/csp/file_frameancestors_userpass.html new file mode 100644 index 0000000000..c840995b6c --- /dev/null +++ b/dom/security/test/csp/file_frameancestors_userpass.html @@ -0,0 +1,10 @@ + + + CSP frame ancestors tests + + + Nested Frames
+
+
+ + diff --git a/dom/security/test/csp/file_frameancestors_userpass_frame_a.html b/dom/security/test/csp/file_frameancestors_userpass_frame_a.html new file mode 100644 index 0000000000..d5a5bb604b --- /dev/null +++ b/dom/security/test/csp/file_frameancestors_userpass_frame_a.html @@ -0,0 +1,12 @@ + + + Nested frame + + + + IFRAME A
+
+ + diff --git a/dom/security/test/csp/file_frameancestors_userpass_frame_b.html b/dom/security/test/csp/file_frameancestors_userpass_frame_b.html new file mode 100644 index 0000000000..87055ef149 --- /dev/null +++ b/dom/security/test/csp/file_frameancestors_userpass_frame_b.html @@ -0,0 +1,12 @@ + + + Nested frame + + + + IFRAME B
+
+ + diff --git a/dom/security/test/csp/file_frameancestors_userpass_frame_c.html b/dom/security/test/csp/file_frameancestors_userpass_frame_c.html new file mode 100644 index 0000000000..159e6c4633 --- /dev/null +++ b/dom/security/test/csp/file_frameancestors_userpass_frame_c.html @@ -0,0 +1,8 @@ + + + Nested frame + + + Nested frame C content + + diff --git a/dom/security/test/csp/file_frameancestors_userpass_frame_c.html^headers^ b/dom/security/test/csp/file_frameancestors_userpass_frame_c.html^headers^ new file mode 100644 index 0000000000..9e7dfefcda --- /dev/null +++ b/dom/security/test/csp/file_frameancestors_userpass_frame_c.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: default-src 'none'; frame-ancestors http://mochi.test:8888/ ; script-src 'self'; diff --git a/dom/security/test/csp/file_frameancestors_userpass_frame_d.html b/dom/security/test/csp/file_frameancestors_userpass_frame_d.html new file mode 100644 index 0000000000..0cb49c4836 --- /dev/null +++ b/dom/security/test/csp/file_frameancestors_userpass_frame_d.html @@ -0,0 +1,8 @@ + + + Nested frame + + + Nested frame D content + + diff --git a/dom/security/test/csp/file_frameancestors_userpass_frame_d.html^headers^ b/dom/security/test/csp/file_frameancestors_userpass_frame_d.html^headers^ new file mode 100644 index 0000000000..019fcea026 --- /dev/null +++ b/dom/security/test/csp/file_frameancestors_userpass_frame_d.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: default-src 'none'; frame-ancestors http://sampleuser:samplepass@example.com/ ; script-src 'self'; diff --git a/dom/security/test/csp/file_hash_source.html b/dom/security/test/csp/file_hash_source.html new file mode 100644 index 0000000000..47eba6cf3e --- /dev/null +++ b/dom/security/test/csp/file_hash_source.html @@ -0,0 +1,65 @@ + + + + +

blocked

+

blocked

+

blocked

+

blocked

+

blocked

+

blocked

+

blocked

+

blocked

+

blocked

+ + + + + + + + + + + + + + + + + + + + + +

+

+

+

+

+

+

+

+

+ + + + + + + + + + + + + + + + + + + + + + diff --git a/dom/security/test/csp/file_hash_source.html^headers^ b/dom/security/test/csp/file_hash_source.html^headers^ new file mode 100644 index 0000000000..785d63391e --- /dev/null +++ b/dom/security/test/csp/file_hash_source.html^headers^ @@ -0,0 +1,2 @@ +Content-Security-Policy: script-src 'sha256-siVR8vAcqP06h2ppeNwqgjr0yZ6yned4X2VF84j4GmI=' 'nonce-jPRxvuRHbiQnCWVuoCMAvQ==' 'sha256-z7rzCkbOJqi08lga3CVQ3b+3948ZbJWaSxsBs8zPliE=' 'sha512-tMLuv22jJ5RHkvLNlv0otvA2fgw6PF16HKu6wy0ZDQ3M7UKzoygs1uxIMSfjMttgWrB5WRvIr35zrTZppMYBVw==' 'sha384-XjAD+FxZfipkxna4id1JrR2QP6OYUZfAxpn9+yHOmT1VSLVa9SQR/dz7CEb7jw7w' 'sha1-LHErkMxKGcSpa/znpzmKYkKnI30=' 'md5-/m4wX3YU+IHs158KwKOBWg=='; style-src 'sha256-UpNH6x+Ux99QTW1fJikQsVbBERJruIC98et0YDVKKHQ=' 'nonce-ftL2UbGHlSEaZTLWMwtA5Q==' 'sha256-0IPbWW5IDJ/juvETq60oTnhC+XzOqdYp5/UBsBKCaOY=' 'sha512-EpcDbSuvFv0HIyKtU5tQMN7UtBMeEbljz1dWPfy7PNCa1RYdHKwdJWT1tie41evq/ZUL1rzadSVdEzq3jl6Twg==' 'sha384-c5W8ON4WyeA2zEOGdrOGhRmRYI8+2UzUUmhGQFjUFP6yiPZx9FGEV3UOiQ+tIshF' 'sha1-T/+b4sxCIiJxDr6XS9dAEyHKt2M=' 'md5-oNrgrtzOZduwDYYi1yo12g=='; +Cache-Control: no-cache diff --git a/dom/security/test/csp/file_iframe_parent_location_js.html b/dom/security/test/csp/file_iframe_parent_location_js.html new file mode 100644 index 0000000000..0d980f9925 --- /dev/null +++ b/dom/security/test/csp/file_iframe_parent_location_js.html @@ -0,0 +1,10 @@ + + + Test setting parent location to javascript: + + + + + diff --git a/dom/security/test/csp/file_iframe_sandbox_document_write.html b/dom/security/test/csp/file_iframe_sandbox_document_write.html new file mode 100644 index 0000000000..a3a0952941 --- /dev/null +++ b/dom/security/test/csp/file_iframe_sandbox_document_write.html @@ -0,0 +1,21 @@ + + + + + + sandboxed with allow-scripts + + diff --git a/dom/security/test/csp/file_iframe_sandbox_srcdoc.html b/dom/security/test/csp/file_iframe_sandbox_srcdoc.html new file mode 100644 index 0000000000..bc700ed68f --- /dev/null +++ b/dom/security/test/csp/file_iframe_sandbox_srcdoc.html @@ -0,0 +1,11 @@ + + + + + Bug 1073952 - CSP should restrict scripts in srcdoc iframe even if sandboxed + + + + + diff --git a/dom/security/test/csp/file_iframe_sandbox_srcdoc.html^headers^ b/dom/security/test/csp/file_iframe_sandbox_srcdoc.html^headers^ new file mode 100644 index 0000000000..cf869e07d4 --- /dev/null +++ b/dom/security/test/csp/file_iframe_sandbox_srcdoc.html^headers^ @@ -0,0 +1 @@ +content-security-policy: default-src *; diff --git a/dom/security/test/csp/file_iframe_srcdoc.sjs b/dom/security/test/csp/file_iframe_srcdoc.sjs new file mode 100644 index 0000000000..25172b58d5 --- /dev/null +++ b/dom/security/test/csp/file_iframe_srcdoc.sjs @@ -0,0 +1,86 @@ +// Custom *.sjs file specifically for the needs of +// https://bugzilla.mozilla.org/show_bug.cgi?id=1073952 + +"use strict"; + +const SCRIPT = ` + `; + +const SIMPLE_IFRAME_SRCDOC = + ` + + + + + + + `; + +const INNER_SRCDOC_IFRAME = ` + `; + +const NESTED_IFRAME_SRCDOC = + ` + + + + + + + `; + +const INNER_DATAURI_IFRAME = ` + `; + +const NESTED_IFRAME_SRCDOC_DATAURI = + ` + + + + + + + `; + +function handleRequest(request, response) { + const query = new URLSearchParams(request.queryString); + + response.setHeader("Cache-Control", "no-cache", false); + if (typeof query.get("csp") === "string") { + response.setHeader("Content-Security-Policy", query.get("csp"), false); + } + response.setHeader("Content-Type", "text/html", false); + + if (query.get("action") === "simple_iframe_srcdoc") { + response.write(SIMPLE_IFRAME_SRCDOC); + return; + } + + if (query.get("action") === "nested_iframe_srcdoc") { + response.write(NESTED_IFRAME_SRCDOC); + return; + } + + if (query.get("action") === "nested_iframe_srcdoc_datauri") { + response.write(NESTED_IFRAME_SRCDOC_DATAURI); + return; + } + + // we should never get here, but just in case + // return something unexpected + response.write("do'h"); +} diff --git a/dom/security/test/csp/file_ignore_unsafe_inline.html b/dom/security/test/csp/file_ignore_unsafe_inline.html new file mode 100644 index 0000000000..773184201c --- /dev/null +++ b/dom/security/test/csp/file_ignore_unsafe_inline.html @@ -0,0 +1,26 @@ + + + +Bug 1004703 - ignore 'unsafe-inline' if nonce- or hash-source specified + + +
a
+ + + + + + + + + + + + + diff --git a/dom/security/test/csp/file_ignore_unsafe_inline_multiple_policies_server.sjs b/dom/security/test/csp/file_ignore_unsafe_inline_multiple_policies_server.sjs new file mode 100644 index 0000000000..32327b7575 --- /dev/null +++ b/dom/security/test/csp/file_ignore_unsafe_inline_multiple_policies_server.sjs @@ -0,0 +1,58 @@ +// custom *.sjs file specifically for the needs of: +// * Bug 1004703 - ignore 'unsafe-inline' if nonce- or hash-source specified +// * Bug 1198422: should not block inline script if default-src is not specified + +const { NetUtil } = ChromeUtils.importESModule( + "resource://gre/modules/NetUtil.sys.mjs" +); + +function loadHTMLFromFile(path) { + // Load the HTML to return in the response from file. + // Since it's relative to the cwd of the test runner, we start there and + // append to get to the actual path of the file. + var testHTMLFile = Cc["@mozilla.org/file/directory_service;1"] + .getService(Ci.nsIProperties) + .get("CurWorkD", Ci.nsIFile); + var dirs = path.split("/"); + for (var i = 0; i < dirs.length; i++) { + testHTMLFile.append(dirs[i]); + } + var testHTMLFileStream = Cc[ + "@mozilla.org/network/file-input-stream;1" + ].createInstance(Ci.nsIFileInputStream); + testHTMLFileStream.init(testHTMLFile, -1, 0, 0); + var testHTML = NetUtil.readInputStreamToString( + testHTMLFileStream, + testHTMLFileStream.available() + ); + return testHTML; +} + +function handleRequest(request, response) { + var query = {}; + request.queryString.split("&").forEach(function (val) { + var [name, value] = val.split("="); + query[name] = unescape(value); + }); + + var csp1 = query.csp1 ? unescape(query.csp1) : ""; + var csp2 = query.csp2 ? unescape(query.csp2) : ""; + var file = unescape(query.file); + + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + // deliver the CSP encoded in the URI + // please note that comma separation of two policies + // acts like sending *two* separate policies + var csp = csp1; + if (csp2 !== "") { + csp += ", " + csp2; + } + response.setHeader("Content-Security-Policy", csp, false); + + // Send HTML to test allowed/blocked behaviors + response.setHeader("Content-Type", "text/html", false); + + response.write(loadHTMLFromFile(file)); +} diff --git a/dom/security/test/csp/file_ignore_xfo.html b/dom/security/test/csp/file_ignore_xfo.html new file mode 100644 index 0000000000..6746a3adba --- /dev/null +++ b/dom/security/test/csp/file_ignore_xfo.html @@ -0,0 +1,10 @@ + + + + + Bug 1024557: Ignore x-frame-options if CSP with frame-ancestors exists + + +
Ignoring XFO because of CSP
+ + diff --git a/dom/security/test/csp/file_ignore_xfo.html^headers^ b/dom/security/test/csp/file_ignore_xfo.html^headers^ new file mode 100644 index 0000000000..e93f9e3ecb --- /dev/null +++ b/dom/security/test/csp/file_ignore_xfo.html^headers^ @@ -0,0 +1,3 @@ +Content-Security-Policy: frame-ancestors http://mochi.test:8888 +X-Frame-Options: deny +Cache-Control: no-cache diff --git a/dom/security/test/csp/file_image_document_pixel.png b/dom/security/test/csp/file_image_document_pixel.png new file mode 100644 index 0000000000..52c591798e Binary files /dev/null and b/dom/security/test/csp/file_image_document_pixel.png differ diff --git a/dom/security/test/csp/file_image_document_pixel.png^headers^ b/dom/security/test/csp/file_image_document_pixel.png^headers^ new file mode 100644 index 0000000000..7c727854d0 --- /dev/null +++ b/dom/security/test/csp/file_image_document_pixel.png^headers^ @@ -0,0 +1,2 @@ +Content-Security-Policy: default-src https://bug1627235.test.com +Cache-Control: no-cache diff --git a/dom/security/test/csp/file_image_nonce.html b/dom/security/test/csp/file_image_nonce.html new file mode 100644 index 0000000000..5d57bb8372 --- /dev/null +++ b/dom/security/test/csp/file_image_nonce.html @@ -0,0 +1,39 @@ + + + + + Bug 1355801: Nonce should not apply to images + + + + + + + + + + diff --git a/dom/security/test/csp/file_image_nonce.html^headers^ b/dom/security/test/csp/file_image_nonce.html^headers^ new file mode 100644 index 0000000000..0d63558c46 --- /dev/null +++ b/dom/security/test/csp/file_image_nonce.html^headers^ @@ -0,0 +1,2 @@ +Content-Security-Policy: img-src 'nonce-abc'; +Cache-Control: no-cache diff --git a/dom/security/test/csp/file_independent_iframe_csp.html b/dom/security/test/csp/file_independent_iframe_csp.html new file mode 100644 index 0000000000..0581f5ea85 --- /dev/null +++ b/dom/security/test/csp/file_independent_iframe_csp.html @@ -0,0 +1,43 @@ + + + + Bug 1419222 - iFrame CSP should not affect parent document CSP + + + + + + + diff --git a/dom/security/test/csp/file_inlinescript.html b/dom/security/test/csp/file_inlinescript.html new file mode 100644 index 0000000000..55a9b9b180 --- /dev/null +++ b/dom/security/test/csp/file_inlinescript.html @@ -0,0 +1,15 @@ + + + CSP inline script tests + + + + + + + testlink + + + diff --git a/dom/security/test/csp/file_inlinestyle_main.html b/dom/security/test/csp/file_inlinestyle_main.html new file mode 100644 index 0000000000..a0d2969883 --- /dev/null +++ b/dom/security/test/csp/file_inlinestyle_main.html @@ -0,0 +1,79 @@ + + + + CSP inline script tests + + + + + + + + + + +
Link tag (external) stylesheet test (should be green)
+
Inline stylesheet test (should be black)
+
Attribute stylesheet test (should be black)
+
cssText test (should be black)
+
modify rule from style sheet via cssText(should be green)
+ + + + + + + This shouldn't be red since the animation should be blocked by CSP. + + + + + + + This shouldn't be red since the animation should be blocked by CSP. + + + + + + + This shouldn't be red since the animation should be blocked by CSP. + + + + + + This shouldn't be red since the <set> should be blocked by CSP. + + + + + diff --git a/dom/security/test/csp/file_inlinestyle_main.html^headers^ b/dom/security/test/csp/file_inlinestyle_main.html^headers^ new file mode 100644 index 0000000000..7b6a251679 --- /dev/null +++ b/dom/security/test/csp/file_inlinestyle_main.html^headers^ @@ -0,0 +1,2 @@ +Content-Security-Policy: default-src 'self' ; script-src 'self' 'unsafe-inline' +Cache-Control: no-cache diff --git a/dom/security/test/csp/file_inlinestyle_main_allowed.html b/dom/security/test/csp/file_inlinestyle_main_allowed.html new file mode 100644 index 0000000000..9b533ef074 --- /dev/null +++ b/dom/security/test/csp/file_inlinestyle_main_allowed.html @@ -0,0 +1,84 @@ + + + + CSP inline script tests + + + + + + + + + + +
Link tag (external) stylesheet test (should be green)
+
Inline stylesheet test (should be green)
+
Attribute stylesheet test (should be green)
+
style.cssText test (should be green)
+
modify rule from style sheet via cssText(should be green)
+ + + + + + + This should be green since the animation should be allowed by CSP. + + + + + + + This should be green since the animation should be allowed by CSP. + + + + + + + This should be green since the animation should be allowed by CSP. + + + + + + This should be green since the <set> should be allowed by CSP. + + + + + diff --git a/dom/security/test/csp/file_inlinestyle_main_allowed.html^headers^ b/dom/security/test/csp/file_inlinestyle_main_allowed.html^headers^ new file mode 100644 index 0000000000..621d2536b0 --- /dev/null +++ b/dom/security/test/csp/file_inlinestyle_main_allowed.html^headers^ @@ -0,0 +1,2 @@ +Content-Security-Policy: default-src 'self' ; script-src 'self' 'unsafe-inline' ; style-src 'self' 'unsafe-inline' +Cache-Control: no-cache diff --git a/dom/security/test/csp/file_invalid_source_expression.html b/dom/security/test/csp/file_invalid_source_expression.html new file mode 100644 index 0000000000..83bb0ec0ca --- /dev/null +++ b/dom/security/test/csp/file_invalid_source_expression.html @@ -0,0 +1,11 @@ + + + + Bug 1086612 - CSP: Let source expression be the empty set in case no valid source can be parsed + + +
blocked
+ + + + diff --git a/dom/security/test/csp/file_leading_wildcard.html b/dom/security/test/csp/file_leading_wildcard.html new file mode 100644 index 0000000000..ea5e993447 --- /dev/null +++ b/dom/security/test/csp/file_leading_wildcard.html @@ -0,0 +1,11 @@ + + + + Bug 1032303 - CSP - Keep FULL STOP when matching *.foo.com to disallow loads from foo.com + + + + + + + diff --git a/dom/security/test/csp/file_link_rel_preload.html b/dom/security/test/csp/file_link_rel_preload.html new file mode 100644 index 0000000000..8af49a77fe --- /dev/null +++ b/dom/security/test/csp/file_link_rel_preload.html @@ -0,0 +1,19 @@ + + + + Bug 1599791 - Test link rel=preload + + + + + + + + + + + + + + + diff --git a/dom/security/test/csp/file_main.html b/dom/security/test/csp/file_main.html new file mode 100644 index 0000000000..ddc8382617 --- /dev/null +++ b/dom/security/test/csp/file_main.html @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
arbitrary good
+
arbitrary_bad
+ + diff --git a/dom/security/test/csp/file_main.html^headers^ b/dom/security/test/csp/file_main.html^headers^ new file mode 100644 index 0000000000..3338de389b --- /dev/null +++ b/dom/security/test/csp/file_main.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: default-src 'self' blob: ; style-src 'unsafe-inline' 'self' diff --git a/dom/security/test/csp/file_main.js b/dom/security/test/csp/file_main.js new file mode 100644 index 0000000000..01dd43cbf5 --- /dev/null +++ b/dom/security/test/csp/file_main.js @@ -0,0 +1,26 @@ +function doXHR(uri) { + try { + var xhr = new XMLHttpRequest(); + xhr.open("GET", uri); + xhr.send(); + } catch (ex) {} +} + +doXHR( + "http://mochi.test:8888/tests/dom/security/test/csp/file_CSP.sjs?testid=xhr_good" +); +doXHR( + "http://example.com/tests/dom/security/test/csp/file_CSP.sjs?testid=xhr_bad" +); +fetch( + "http://mochi.test:8888/tests/dom/security/test/csp/file_CSP.sjs?testid=fetch_good" +); +fetch( + "http://example.com/tests/dom/security/test/csp/file_CSP.sjs?testid=fetch_bad" +); +navigator.sendBeacon( + "http://mochi.test:8888/tests/dom/security/test/csp/file_CSP.sjs?testid=beacon_good" +); +navigator.sendBeacon( + "http://example.com/tests/dom/security/test/csp/file_CSP.sjs?testid=beacon_bad" +); diff --git a/dom/security/test/csp/file_meta_element.html b/dom/security/test/csp/file_meta_element.html new file mode 100644 index 0000000000..17f19c7c86 --- /dev/null +++ b/dom/security/test/csp/file_meta_element.html @@ -0,0 +1,27 @@ + + + + + + Bug 663570 - Implement Content Security Policy via meta tag + + + + + + + + + + diff --git a/dom/security/test/csp/file_meta_header_dual.sjs b/dom/security/test/csp/file_meta_header_dual.sjs new file mode 100644 index 0000000000..445b3e444e --- /dev/null +++ b/dom/security/test/csp/file_meta_header_dual.sjs @@ -0,0 +1,101 @@ +// Custom *.sjs file specifically for the needs of Bug: +// Bug 663570 - Implement Content Security Policy via meta tag + +const HTML_HEAD = + "" + + "" + + "" + + "" + + "Bug 663570 - Implement Content Security Policy via <meta> tag"; + +const HTML_BODY = + "" + + "" + + "" + + "" + + "" + + ""; + +const META_CSP_BLOCK_IMG = + ''; + +const META_CSP_ALLOW_IMG = + ''; + +const HEADER_CSP_BLOCK_IMG = "img-src 'none';"; + +const HEADER_CSP_ALLOW_IMG = "img-src http://mochi.test:8888"; + +function handleRequest(request, response) { + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/html", false); + var queryString = request.queryString; + + if (queryString === "test1") { + /* load image without any CSP */ + response.write(HTML_HEAD + HTML_BODY); + return; + } + + if (queryString === "test2") { + /* load image where meta denies load */ + response.write(HTML_HEAD + META_CSP_BLOCK_IMG + HTML_BODY); + return; + } + + if (queryString === "test3") { + /* load image where meta allows load */ + response.write(HTML_HEAD + META_CSP_ALLOW_IMG + HTML_BODY); + return; + } + + if (queryString === "test4") { + /* load image where meta allows but header blocks */ + response.setHeader("Content-Security-Policy", HEADER_CSP_BLOCK_IMG, false); + response.write(HTML_HEAD + META_CSP_ALLOW_IMG + HTML_BODY); + return; + } + + if (queryString === "test5") { + /* load image where meta blocks but header allows */ + response.setHeader("Content-Security-Policy", HEADER_CSP_ALLOW_IMG, false); + response.write(HTML_HEAD + META_CSP_BLOCK_IMG + HTML_BODY); + return; + } + + if (queryString === "test6") { + /* load image where meta allows and header allows */ + response.setHeader("Content-Security-Policy", HEADER_CSP_ALLOW_IMG, false); + response.write(HTML_HEAD + META_CSP_ALLOW_IMG + HTML_BODY); + return; + } + + if (queryString === "test7") { + /* load image where meta1 allows but meta2 blocks */ + response.write( + HTML_HEAD + META_CSP_ALLOW_IMG + META_CSP_BLOCK_IMG + HTML_BODY + ); + return; + } + + if (queryString === "test8") { + /* load image where meta1 allows and meta2 allows */ + response.write( + HTML_HEAD + META_CSP_ALLOW_IMG + META_CSP_ALLOW_IMG + HTML_BODY + ); + return; + } + + // we should never get here, but just in case, return + // something unexpected + response.write("do'h"); +} diff --git a/dom/security/test/csp/file_meta_whitespace_skipping.html b/dom/security/test/csp/file_meta_whitespace_skipping.html new file mode 100644 index 0000000000..c0cfc8cc28 --- /dev/null +++ b/dom/security/test/csp/file_meta_whitespace_skipping.html @@ -0,0 +1,31 @@ + + + + + + + Bug 1261634 - Update whitespace skipping for meta csp + + + + + + diff --git a/dom/security/test/csp/file_multi_policy_injection_bypass.html b/dom/security/test/csp/file_multi_policy_injection_bypass.html new file mode 100644 index 0000000000..a3cb415a9e --- /dev/null +++ b/dom/security/test/csp/file_multi_policy_injection_bypass.html @@ -0,0 +1,15 @@ + + + + + + + + + + + + + diff --git a/dom/security/test/csp/file_multi_policy_injection_bypass.html^headers^ b/dom/security/test/csp/file_multi_policy_injection_bypass.html^headers^ new file mode 100644 index 0000000000..e1b64a9220 --- /dev/null +++ b/dom/security/test/csp/file_multi_policy_injection_bypass.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: default-src 'self', default-src * diff --git a/dom/security/test/csp/file_multi_policy_injection_bypass_2.html b/dom/security/test/csp/file_multi_policy_injection_bypass_2.html new file mode 100644 index 0000000000..3fa6c7ab91 --- /dev/null +++ b/dom/security/test/csp/file_multi_policy_injection_bypass_2.html @@ -0,0 +1,15 @@ + + + + + + + + + + + + + diff --git a/dom/security/test/csp/file_multi_policy_injection_bypass_2.html^headers^ b/dom/security/test/csp/file_multi_policy_injection_bypass_2.html^headers^ new file mode 100644 index 0000000000..b523073cd3 --- /dev/null +++ b/dom/security/test/csp/file_multi_policy_injection_bypass_2.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: default-src 'self' , default-src * diff --git a/dom/security/test/csp/file_multipart_testserver.sjs b/dom/security/test/csp/file_multipart_testserver.sjs new file mode 100644 index 0000000000..571dd4006d --- /dev/null +++ b/dom/security/test/csp/file_multipart_testserver.sjs @@ -0,0 +1,160 @@ +// SJS file specifically for the needs of bug +// Bug 1416045/Bug 1223743 - CSP: Check baseChannel for CSP when loading multipart channel + +var CSP = "script-src 'unsafe-inline', img-src 'none'"; +var rootCSP = "script-src 'unsafe-inline'"; +var part1CSP = "img-src *"; +var part2CSP = "img-src 'none'"; +var BOUNDARY = "fooboundary"; + +// small red image +const IMG_BYTES = atob( + "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12" + + "P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" +); + +var RESPONSE = ` + +`; + +var RESPONSE1 = ` + + + +`; + +var RESPONSE2 = ` + + + +`; + +function setGlobalState(data, key) { + x = { + data, + QueryInterface(iid) { + return this; + }, + }; + x.wrappedJSObject = x; + setObjectState(key, x); +} + +function getGlobalState(key) { + var data; + getObjectState(key, function (x) { + data = x && x.wrappedJSObject.data; + }); + return data; +} + +function handleRequest(request, response) { + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + if (request.queryString == "doc") { + response.setHeader("Content-Security-Policy", CSP, false); + response.setHeader( + "Content-Type", + "multipart/x-mixed-replace; boundary=" + BOUNDARY, + false + ); + response.write(BOUNDARY + "\r\n"); + response.write(RESPONSE); + response.write(BOUNDARY + "\r\n"); + return; + } + + if (request.queryString == "partcspdoc") { + response.setHeader("Content-Security-Policy", rootCSP, false); + response.setHeader( + "Content-Type", + "multipart/x-mixed-replace; boundary=" + BOUNDARY, + false + ); + response.setStatusLine(request.httpVersion, 200, "OK"); + response.processAsync(); + response.write("--" + BOUNDARY + "\r\n"); + sendNextPart(response, 1); + return; + } + + if (request.queryString == "sendnextpart") { + response.setStatusLine(request.httpVersion, 204, "No content"); + var blockedResponse = getGlobalState("root-document-response"); + if (typeof blockedResponse == "object") { + sendNextPart(blockedResponse, 2); + sendClose(blockedResponse); + } else { + dump("Couldn't find the stored response object."); + } + return; + } + + if (request.queryString == "img") { + response.setHeader("Content-Type", "image/png"); + response.write(IMG_BYTES); + return; + } + + // we should never get here - return something unexpected + response.write("d'oh"); +} + +function sendClose(response) { + response.write("--" + BOUNDARY + "--\r\n"); + response.finish(); +} + +function sendNextPart(response, partNumber) { + response.write("Content-type: text/html" + "\r\n"); + if (partNumber == 1) { + response.write("Content-Security-Policy:" + part1CSP + "\r\n"); + response.write(RESPONSE1); + setGlobalState(response, "root-document-response"); + } else { + response.write("Content-Security-Policy:" + part2CSP + "\r\n"); + response.write(RESPONSE2); + } + response.write("--" + BOUNDARY + "\r\n"); +} diff --git a/dom/security/test/csp/file_no_log_ignore_xfo.html b/dom/security/test/csp/file_no_log_ignore_xfo.html new file mode 100644 index 0000000000..fc5528a35c --- /dev/null +++ b/dom/security/test/csp/file_no_log_ignore_xfo.html @@ -0,0 +1,10 @@ + + + + + Bug 1722252: "Content-Security-Policy: Ignoring ‘x-frame-options’ because of ‘frame-ancestors’ directive." warning message even when no "x-frame-options" header present + + +
Do not log xfo ignore warning when no xfo is set.
+ + diff --git a/dom/security/test/csp/file_no_log_ignore_xfo.html^headers^ b/dom/security/test/csp/file_no_log_ignore_xfo.html^headers^ new file mode 100644 index 0000000000..1fbbf3de99 --- /dev/null +++ b/dom/security/test/csp/file_no_log_ignore_xfo.html^headers^ @@ -0,0 +1,2 @@ +Content-Security-Policy: frame-ancestors http://mochi.test:8888 +Cache-Control: no-cache diff --git a/dom/security/test/csp/file_nonce_redirector.sjs b/dom/security/test/csp/file_nonce_redirector.sjs new file mode 100644 index 0000000000..b56b9ded37 --- /dev/null +++ b/dom/security/test/csp/file_nonce_redirector.sjs @@ -0,0 +1,28 @@ +// custom *.sjs file for +// Bug 1469150:Scripts with valid nonce get blocked if URL redirects. + +const URL_PATH = "example.com/tests/dom/security/test/csp/"; + +function handleRequest(request, response) { + response.setHeader("Cache-Control", "no-cache", false); + let queryStr = request.queryString; + + if (queryStr === "redirect") { + response.setStatusLine("1.1", 302, "Found"); + response.setHeader( + "Location", + "https://" + URL_PATH + "file_nonce_redirector.sjs?load", + false + ); + return; + } + + if (queryStr === "load") { + response.setHeader("Content-Type", "application/javascript", false); + response.write("console.log('script loaded');"); + return; + } + + // we should never get here - return something unexpected + response.write("d'oh"); +} diff --git a/dom/security/test/csp/file_nonce_redirects.html b/dom/security/test/csp/file_nonce_redirects.html new file mode 100644 index 0000000000..e291164900 --- /dev/null +++ b/dom/security/test/csp/file_nonce_redirects.html @@ -0,0 +1,23 @@ + + + + + + Bug 1469150:Scripts with valid nonce get blocked if URL redirects + + + + + + + + diff --git a/dom/security/test/csp/file_nonce_snapshot.sjs b/dom/security/test/csp/file_nonce_snapshot.sjs new file mode 100644 index 0000000000..2b114fd87e --- /dev/null +++ b/dom/security/test/csp/file_nonce_snapshot.sjs @@ -0,0 +1,54 @@ +"use strict"; + +const TEST_FRAME = ` + + + + + + `; + +const SCRIPT = "window.parent.postMessage('script-loaded', '*');"; + +function handleRequest(request, response) { + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + let queryString = request.queryString; + + if (queryString === "load-frame") { + response.setHeader( + "Content-Security-Policy", + "script-src 'nonce-123456789'", + false + ); + response.setHeader("Content-Type", "text/html", false); + response.write(TEST_FRAME); + return; + } + + if (queryString === "redir-script") { + response.setStatusLine("1.1", 302, "Found"); + response.setHeader( + "Location", + "file_nonce_snapshot.sjs?load-script", + false + ); + return; + } + + if (queryString === "load-script") { + response.setHeader("Content-Type", "application/javascript", false); + response.write(SCRIPT); + return; + } + + // we should never get here but just in case return something unexpected + response.write("do'h"); +} diff --git a/dom/security/test/csp/file_nonce_source.html b/dom/security/test/csp/file_nonce_source.html new file mode 100644 index 0000000000..01d4046c37 --- /dev/null +++ b/dom/security/test/csp/file_nonce_source.html @@ -0,0 +1,73 @@ + + + + + + + + + + + +
    +
  1. (inline script with correct nonce) This text should be green.
  2. +
  3. (inline script with incorrect nonce) This text should be black.
  4. +
  5. (inline script with correct nonce for styles, but not for scripts) This text should be black.
  6. +
  7. (inline script with no nonce) This text should be black.
  8. +
+ + + + + + + + + + + + + + + + + + + + +
    +
  1. + (inline style with correct nonce) This text should be green +
  2. +
  3. + (inline style with incorrect nonce) This text should be black +
  4. +
  5. + (inline style with correct script, not style, nonce) This text should be black +
  6. +
  7. + (inline style with no nonce) This text should be black +
  8. +
+ + + + + + diff --git a/dom/security/test/csp/file_nonce_source.html^headers^ b/dom/security/test/csp/file_nonce_source.html^headers^ new file mode 100644 index 0000000000..865e5fe984 --- /dev/null +++ b/dom/security/test/csp/file_nonce_source.html^headers^ @@ -0,0 +1,2 @@ +Content-Security-Policy: script-src 'self' 'nonce-correctscriptnonce' 'nonce-anothercorrectscriptnonce'; style-src 'nonce-correctstylenonce'; +Cache-Control: no-cache diff --git a/dom/security/test/csp/file_null_baseuri.html b/dom/security/test/csp/file_null_baseuri.html new file mode 100644 index 0000000000..f995688b13 --- /dev/null +++ b/dom/security/test/csp/file_null_baseuri.html @@ -0,0 +1,21 @@ + + + + Bug 1121857 - document.baseURI should not get blocked if baseURI is null + + + + + diff --git a/dom/security/test/csp/file_object_inherit.html b/dom/security/test/csp/file_object_inherit.html new file mode 100644 index 0000000000..76c9764162 --- /dev/null +++ b/dom/security/test/csp/file_object_inherit.html @@ -0,0 +1,21 @@ + + + + Bug 1457100: Test OBJECT inherits CSP if needed + + + + + + + + + + diff --git a/dom/security/test/csp/file_parent_location_js.html b/dom/security/test/csp/file_parent_location_js.html new file mode 100644 index 0000000000..9c56f49905 --- /dev/null +++ b/dom/security/test/csp/file_parent_location_js.html @@ -0,0 +1,18 @@ + + + Test setting parent location to javascript: + + + + + + + diff --git a/dom/security/test/csp/file_path_matching.html b/dom/security/test/csp/file_path_matching.html new file mode 100644 index 0000000000..662fbfb8af --- /dev/null +++ b/dom/security/test/csp/file_path_matching.html @@ -0,0 +1,10 @@ + + + + Bug 808292 - Implement path-level host-source matching to CSP + + +
blocked
+ + + diff --git a/dom/security/test/csp/file_path_matching.js b/dom/security/test/csp/file_path_matching.js new file mode 100644 index 0000000000..09286d42e9 --- /dev/null +++ b/dom/security/test/csp/file_path_matching.js @@ -0,0 +1 @@ +document.getElementById("testdiv").innerHTML = "allowed"; diff --git a/dom/security/test/csp/file_path_matching_incl_query.html b/dom/security/test/csp/file_path_matching_incl_query.html new file mode 100644 index 0000000000..50af2b1437 --- /dev/null +++ b/dom/security/test/csp/file_path_matching_incl_query.html @@ -0,0 +1,10 @@ + + + + Bug 1147026 - CSP should ignore query string when checking a resource load + + +
blocked
+ + + diff --git a/dom/security/test/csp/file_path_matching_redirect.html b/dom/security/test/csp/file_path_matching_redirect.html new file mode 100644 index 0000000000..a16cc90ec6 --- /dev/null +++ b/dom/security/test/csp/file_path_matching_redirect.html @@ -0,0 +1,10 @@ + + + + Bug 808292 - Implement path-level host-source matching to CSP + + +
blocked
+ + + diff --git a/dom/security/test/csp/file_path_matching_redirect_server.sjs b/dom/security/test/csp/file_path_matching_redirect_server.sjs new file mode 100644 index 0000000000..bed3a1dccf --- /dev/null +++ b/dom/security/test/csp/file_path_matching_redirect_server.sjs @@ -0,0 +1,12 @@ +// Redirect server specifically to handle redirects +// for path-level host-source matching +// see https://bugzilla.mozilla.org/show_bug.cgi?id=808292 + +function handleRequest(request, response) { + var newLocation = + "http://test1.example.com/tests/dom/security/test/csp/file_path_matching.js"; + + response.setStatusLine("1.1", 302, "Found"); + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Location", newLocation, false); +} diff --git a/dom/security/test/csp/file_pdfjs_not_subject_to_csp.html b/dom/security/test/csp/file_pdfjs_not_subject_to_csp.html new file mode 100644 index 0000000000..da5c7f0a6e --- /dev/null +++ b/dom/security/test/csp/file_pdfjs_not_subject_to_csp.html @@ -0,0 +1,21 @@ + + + + + + +
+ + + + diff --git a/dom/security/test/csp/file_ping.html b/dom/security/test/csp/file_ping.html new file mode 100644 index 0000000000..8aaf34cc3a --- /dev/null +++ b/dom/security/test/csp/file_ping.html @@ -0,0 +1,19 @@ + + + + Bug 1100181 - CSP: Enforce connect-src when submitting pings + + + + + Send ping + + + + + diff --git a/dom/security/test/csp/file_policyuri_regression_from_multipolicy.html b/dom/security/test/csp/file_policyuri_regression_from_multipolicy.html new file mode 100644 index 0000000000..2a75eef7e8 --- /dev/null +++ b/dom/security/test/csp/file_policyuri_regression_from_multipolicy.html @@ -0,0 +1,9 @@ + + + +
Inline script didn't run
+ + + diff --git a/dom/security/test/csp/file_policyuri_regression_from_multipolicy.html^headers^ b/dom/security/test/csp/file_policyuri_regression_from_multipolicy.html^headers^ new file mode 100644 index 0000000000..c4ff8ea9fd --- /dev/null +++ b/dom/security/test/csp/file_policyuri_regression_from_multipolicy.html^headers^ @@ -0,0 +1 @@ +content-security-policy-report-only: policy-uri /tests/dom/security/test/csp/file_policyuri_regression_from_multipolicy_policy diff --git a/dom/security/test/csp/file_policyuri_regression_from_multipolicy_policy b/dom/security/test/csp/file_policyuri_regression_from_multipolicy_policy new file mode 100644 index 0000000000..a5c610cd7b --- /dev/null +++ b/dom/security/test/csp/file_policyuri_regression_from_multipolicy_policy @@ -0,0 +1 @@ +default-src 'self'; diff --git a/dom/security/test/csp/file_punycode_host_src.js b/dom/security/test/csp/file_punycode_host_src.js new file mode 100644 index 0000000000..9728e2fecc --- /dev/null +++ b/dom/security/test/csp/file_punycode_host_src.js @@ -0,0 +1,2 @@ +const LOADED = true; +parent.postMessage({ result: "script-allowed" }, "*"); diff --git a/dom/security/test/csp/file_punycode_host_src.sjs b/dom/security/test/csp/file_punycode_host_src.sjs new file mode 100644 index 0000000000..99f76d5317 --- /dev/null +++ b/dom/security/test/csp/file_punycode_host_src.sjs @@ -0,0 +1,46 @@ +// custom *.sjs for Bug 1224225 +// Punycode in CSP host sources + +const HTML_PART1 = + "" + + '' + + "Bug 1224225 - CSP source matching should work for punycoded domain names" + + "" + + "" + + "" + + "" + + ""; + +function handleRequest(request, response) { + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/html", false); + + const query = new URLSearchParams(request.queryString); + + if (query.get("csp")) { + response.setHeader("Content-Security-Policy", query.get("csp"), false); + } + if (query.get("action") == "script-unicode-csp-punycode") { + response.write(HTML_PART1 + TESTCASE1 + HTML_PART2); + return; + } + if (query.get("action") == "script-punycode-csp-punycode") { + response.write(HTML_PART1 + TESTCASE2 + HTML_PART2); + return; + } + + // we should never get here, but just in case + // return something unexpected + response.write("do'h"); +} diff --git a/dom/security/test/csp/file_redirect_content.sjs b/dom/security/test/csp/file_redirect_content.sjs new file mode 100644 index 0000000000..8d7d6a8224 --- /dev/null +++ b/dom/security/test/csp/file_redirect_content.sjs @@ -0,0 +1,39 @@ +// https://bugzilla.mozilla.org/show_bug.cgi?id=650386 +// This SJS file serves file_redirect_content.html +// with a CSP that will trigger a violation and that will report it +// to file_redirect_report.sjs +// +// This handles 301, 302, 303 and 307 redirects. The HTTP status code +// returned/type of redirect to do comes from the query string +// parameter passed in from the test_bug650386_* files and then also +// uses that value in the report-uri parameter of the CSP +function handleRequest(request, response) { + response.setHeader("Cache-Control", "no-cache", false); + + // this gets used in the CSP as part of the report URI. + var redirect = request.queryString; + + if (redirect < 301 || (redirect > 303 && redirect <= 306) || redirect > 307) { + // if we somehow got some bogus redirect code here, + // do a 302 redirect to the same URL as the report URI + // redirects to - this will fail the test. + var loc = "http://example.com/some/fake/path"; + response.setStatusLine("1.1", 302, "Found"); + response.setHeader("Location", loc, false); + return; + } + + var csp = + "default-src 'self';report-uri http://mochi.test:8888/tests/dom/security/test/csp/file_redirect_report.sjs?" + + redirect; + + response.setHeader("Content-Security-Policy", csp, false); + + // the actual file content. + // this image load will (intentionally) fail due to the CSP policy of default-src: 'self' + // specified by the CSP string above. + var content = + ''; + + response.write(content); +} diff --git a/dom/security/test/csp/file_redirect_report.sjs b/dom/security/test/csp/file_redirect_report.sjs new file mode 100644 index 0000000000..42b69357b7 --- /dev/null +++ b/dom/security/test/csp/file_redirect_report.sjs @@ -0,0 +1,16 @@ +// https://bugzilla.mozilla.org/show_bug.cgi?id=650386 +// This SJS file serves as CSP violation report target +// and issues a redirect, to make sure the browser does not post to the target +// of the redirect, per CSP spec. +// This handles 301, 302, 303 and 307 redirects. The HTTP status code +// returned/type of redirect to do comes from the query string +// parameter +function handleRequest(request, response) { + response.setHeader("Cache-Control", "no-cache", false); + + var redirect = request.queryString; + + var loc = "http://example.com/some/fake/path"; + response.setStatusLine("1.1", redirect, "Found"); + response.setHeader("Location", loc, false); +} diff --git a/dom/security/test/csp/file_redirect_worker.sjs b/dom/security/test/csp/file_redirect_worker.sjs new file mode 100644 index 0000000000..5cf211484e --- /dev/null +++ b/dom/security/test/csp/file_redirect_worker.sjs @@ -0,0 +1,34 @@ +// SJS file to serve resources for CSP redirect tests +// This file redirects to a specified resource. +const THIS_SITE = "http://mochi.test:8888"; +const OTHER_SITE = "http://example.com"; + +function handleRequest(request, response) { + var query = {}; + request.queryString.split("&").forEach(function (val) { + var [name, value] = val.split("="); + query[name] = unescape(value); + }); + + var resource = query.path; + + response.setHeader("Cache-Control", "no-cache", false); + var loc = ""; + + // redirect to a resource on this site + if (query.redir == "same") { + loc = THIS_SITE + resource + "#" + query.page_id; + } + + // redirect to a resource on a different site + else if (query.redir == "other") { + loc = OTHER_SITE + resource + "#" + query.page_id; + } + + response.setStatusLine("1.1", 302, "Found"); + response.setHeader("Location", loc, false); + + response.write( + '' + ); +} diff --git a/dom/security/test/csp/file_redirects_main.html b/dom/security/test/csp/file_redirects_main.html new file mode 100644 index 0000000000..d05af88fe8 --- /dev/null +++ b/dom/security/test/csp/file_redirects_main.html @@ -0,0 +1,37 @@ + + +CSP redirect tests + + +
+ + + + diff --git a/dom/security/test/csp/file_redirects_page.sjs b/dom/security/test/csp/file_redirects_page.sjs new file mode 100644 index 0000000000..0ce9cc75ec --- /dev/null +++ b/dom/security/test/csp/file_redirects_page.sjs @@ -0,0 +1,140 @@ +// SJS file for CSP redirect mochitests +// This file serves pages which can optionally specify a Content Security Policy +function handleRequest(request, response) { + var query = {}; + request.queryString.split("&").forEach(function (val) { + var [name, value] = val.split("="); + query[name] = unescape(value); + }); + + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/html", false); + + var resource = "/tests/dom/security/test/csp/file_redirects_resource.sjs"; + + // CSP header value + response.setHeader( + "Content-Security-Policy", + "default-src 'self' blob: ; style-src 'self' 'unsafe-inline'", + false + ); + + // downloadable font that redirects to another site + if (query.testid == "font-src") { + var resp = + '' + + '
test
'; + response.write(resp); + return; + } + + // iframe that redirects to another site + if (query.testid == "frame-src") { + response.write( + '' + ); + return; + } + + // image that redirects to another site + if (query.testid == "img-src") { + response.write( + '' + ); + return; + } + + // video content that redirects to another site + if (query.testid == "media-src") { + response.write( + '' + ); + return; + } + + // object content that redirects to another site + if (query.testid == "object-src") { + response.write( + '' + ); + return; + } + + // external script that redirects to another site + if (query.testid == "script-src") { + response.write( + '' + ); + return; + } + + // external stylesheet that redirects to another site + if (query.testid == "style-src") { + response.write( + '' + ); + return; + } + + // script that XHR's to a resource that redirects to another site + if (query.testid == "xhr-src") { + response.write(''); + return; + } + + // for bug949706 + if (query.testid == "img-src-from-css") { + // loads a stylesheet, which in turn loads an image that redirects. + response.write( + '' + ); + return; + } + + if (query.testid == "from-worker") { + // loads a script; launches a worker; that worker uses importscript; which then gets redirected + // So it's: + // ' + ); + return; + } + + if (query.testid == "from-blob-worker") { + // loads a script; launches a worker; that worker uses importscript; which then gets redirected + // So it's: + // ' + ); + } +} diff --git a/dom/security/test/csp/file_redirects_resource.sjs b/dom/security/test/csp/file_redirects_resource.sjs new file mode 100644 index 0000000000..df0b8101d8 --- /dev/null +++ b/dom/security/test/csp/file_redirects_resource.sjs @@ -0,0 +1,171 @@ +// SJS file to serve resources for CSP redirect tests +// This file mimics serving resources, e.g. fonts, images, etc., which a CSP +// can include. The resource may redirect to a different resource, if specified. +function handleRequest(request, response) { + var query = {}; + request.queryString.split("&").forEach(function (val) { + var [name, value] = val.split("="); + query[name] = unescape(value); + }); + + var thisSite = "http://mochi.test:8888"; + var otherSite = "http://example.com"; + var resource = "/tests/dom/security/test/csp/file_redirects_resource.sjs"; + + response.setHeader("Cache-Control", "no-cache", false); + + // redirect to a resource on this site + if (query.redir == "same") { + var loc = thisSite + resource + "?res=" + query.res + "&testid=" + query.id; + response.setStatusLine("1.1", 302, "Found"); + response.setHeader("Location", loc, false); + return; + } + + // redirect to a resource on a different site + else if (query.redir == "other") { + var loc = + otherSite + resource + "?res=" + query.res + "&testid=" + query.id; + response.setStatusLine("1.1", 302, "Found"); + response.setHeader("Location", loc, false); + return; + } + + // not a redirect. serve some content. + // the content doesn't have to be valid, since we're only checking whether + // the request for the content was sent or not. + + // downloadable font + if (query.res == "font") { + response.setHeader("Access-Control-Allow-Origin", "*", false); + response.setHeader("Content-Type", "text/plain", false); + response.write("font data..."); + return; + } + + // iframe with arbitrary content + if (query.res == "iframe") { + response.setHeader("Content-Type", "text/html", false); + response.write("iframe content..."); + return; + } + + // image + if (query.res == "image") { + response.setHeader("Content-Type", "image/gif", false); + response.write("image data..."); + return; + } + + // media content, e.g. Ogg video + if (query.res == "media") { + response.setHeader("Content-Type", "video/ogg", false); + response.write("video data..."); + return; + } + + // plugin content, e.g. + if (query.res == "object") { + response.setHeader("Content-Type", "text/html", false); + response.write("object data..."); + return; + } + + // script + if (query.res == "script") { + response.setHeader("Content-Type", "application/javascript", false); + response.write("some script..."); + return; + } + + // external stylesheet + if (query.res == "style") { + response.setHeader("Content-Type", "text/css", false); + response.write("css data..."); + return; + } + + // internal stylesheet that loads an image from an external site + if (query.res == "cssLoader") { + let bgURL = thisSite + resource + "?redir=other&res=image&id=" + query.id; + response.setHeader("Content-Type", "text/css", false); + response.write("body { background:url('" + bgURL + "'); }"); + return; + } + + // script that loads an internal worker that uses importScripts on a redirect + // to an external script. + if (query.res == "loadWorkerThatMakesRequests") { + // this creates a worker (same origin) that imports a redirecting script. + let workerURL = + thisSite + resource + "?res=makeRequestsWorker&id=" + query.id; + response.setHeader("Content-Type", "application/javascript", false); + response.write("new Worker('" + workerURL + "');"); + return; + } + + // script that loads an internal worker that uses importScripts on a redirect + // to an external script. + if (query.res == "loadBlobWorkerThatMakesRequests") { + // this creates a worker (same origin) that imports a redirecting script. + let workerURL = + thisSite + resource + "?res=makeRequestsWorker&id=" + query.id; + response.setHeader("Content-Type", "application/javascript", false); + response.write( + "var x = new XMLHttpRequest(); x.open('GET', '" + workerURL + "'); " + ); + response.write("x.responseType = 'blob'; x.send(); "); + response.write( + "x.onload = () => { new Worker(URL.createObjectURL(x.response)); };" + ); + return; + } + + // source for a worker that simply calls importScripts on a script that + // redirects. + if (query.res == "makeRequestsWorker") { + // this is code for a worker that imports a redirected script. + let scriptURL = + thisSite + + resource + + "?redir=other&res=script&id=script-src-redir-" + + query.id; + let xhrURL = + thisSite + + resource + + "?redir=other&res=xhr-resp&id=xhr-src-redir-" + + query.id; + let fetchURL = + thisSite + + resource + + "?redir=other&res=xhr-resp&id=fetch-src-redir-" + + query.id; + response.setHeader("Content-Type", "application/javascript", false); + response.write("try { importScripts('" + scriptURL + "'); } catch(ex) {} "); + response.write( + "var x = new XMLHttpRequest(); x.open('GET', '" + xhrURL + "'); x.send();" + ); + response.write("fetch('" + fetchURL + "');"); + return; + } + + // script that invokes XHR + if (query.res == "xhr") { + response.setHeader("Content-Type", "application/javascript", false); + var resp = + 'var x = new XMLHttpRequest();x.open("GET", "' + + thisSite + + resource + + '?redir=other&res=xhr-resp&id=xhr-src-redir", false);\n' + + "x.send(null);"; + response.write(resp); + return; + } + + // response to XHR + if (query.res == "xhr-resp") { + response.setHeader("Access-Control-Allow-Origin", "*", false); + response.setHeader("Content-Type", "text/html", false); + response.write("XHR response..."); + } +} diff --git a/dom/security/test/csp/file_report.html b/dom/security/test/csp/file_report.html new file mode 100644 index 0000000000..fb18af8057 --- /dev/null +++ b/dom/security/test/csp/file_report.html @@ -0,0 +1,13 @@ + + + + Bug 1033424 - Test csp-report properties + + + + + diff --git a/dom/security/test/csp/file_report_chromescript.js b/dom/security/test/csp/file_report_chromescript.js new file mode 100644 index 0000000000..8c8ddcf0a0 --- /dev/null +++ b/dom/security/test/csp/file_report_chromescript.js @@ -0,0 +1,68 @@ +/* eslint-env mozilla/chrome-script */ + +const { NetUtil } = ChromeUtils.importESModule( + "resource://gre/modules/NetUtil.sys.mjs" +); + +// eslint-disable-next-line mozilla/reject-importGlobalProperties +Cu.importGlobalProperties(["TextDecoder"]); + +const reportURI = "http://mochi.test:8888/foo.sjs"; + +var openingObserver = { + observe(subject, topic, data) { + // subject should be an nsURI + if (subject.QueryInterface == undefined) { + return; + } + + var message = { report: "", error: false }; + + if (topic == "http-on-opening-request") { + var asciiSpec = subject.QueryInterface(Ci.nsIHttpChannel).URI.asciiSpec; + if (asciiSpec !== reportURI) { + return; + } + + var reportText = false; + try { + // Verify that the report was properly formatted. + // We'll parse the report text as JSON and verify that the properties + // have expected values. + var reportText = "{}"; + var uploadStream = subject.QueryInterface( + Ci.nsIUploadChannel + ).uploadStream; + + if (uploadStream) { + // get the bytes from the request body + var binstream = Cc["@mozilla.org/binaryinputstream;1"].createInstance( + Ci.nsIBinaryInputStream + ); + binstream.setInputStream(uploadStream); + + let bytes = NetUtil.readInputStream(binstream); + + // rewind stream as we are supposed to - there will be an assertion later if we don't. + uploadStream + .QueryInterface(Ci.nsISeekableStream) + .seek(Ci.nsISeekableStream.NS_SEEK_SET, 0); + + let textDecoder = new TextDecoder(); + reportText = textDecoder.decode(bytes); + } + + message.report = reportText; + } catch (e) { + message.error = e.toString(); + } + + sendAsyncMessage("opening-request-completed", message); + } + }, +}; + +Services.obs.addObserver(openingObserver, "http-on-opening-request"); +addMessageListener("finish", function () { + Services.obs.removeObserver(openingObserver, "http-on-opening-request"); +}); diff --git a/dom/security/test/csp/file_report_font_cache-1.html b/dom/security/test/csp/file_report_font_cache-1.html new file mode 100644 index 0000000000..59b4908f83 --- /dev/null +++ b/dom/security/test/csp/file_report_font_cache-1.html @@ -0,0 +1,26 @@ + + +

A

+

A

+

A

+ diff --git a/dom/security/test/csp/file_report_font_cache-2.html b/dom/security/test/csp/file_report_font_cache-2.html new file mode 100644 index 0000000000..cea9cea663 --- /dev/null +++ b/dom/security/test/csp/file_report_font_cache-2.html @@ -0,0 +1,25 @@ + + +

A

+ diff --git a/dom/security/test/csp/file_report_font_cache-2.html^headers^ b/dom/security/test/csp/file_report_font_cache-2.html^headers^ new file mode 100644 index 0000000000..493f850baa --- /dev/null +++ b/dom/security/test/csp/file_report_font_cache-2.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: font-src 'none'; report-uri http://mochi.test:8888/foo.sjs diff --git a/dom/security/test/csp/file_report_for_import.css b/dom/security/test/csp/file_report_for_import.css new file mode 100644 index 0000000000..b578b77b33 --- /dev/null +++ b/dom/security/test/csp/file_report_for_import.css @@ -0,0 +1 @@ +@import url("http://example.com/tests/dom/security/test/csp/file_report_for_import_server.sjs?stylesheet"); diff --git a/dom/security/test/csp/file_report_for_import.html b/dom/security/test/csp/file_report_for_import.html new file mode 100644 index 0000000000..77a36faea1 --- /dev/null +++ b/dom/security/test/csp/file_report_for_import.html @@ -0,0 +1,10 @@ + + + + Bug 1048048 - Test sending csp-report when using import in css + + + + empty body, just testing @import in the included css for bug 1048048 + + diff --git a/dom/security/test/csp/file_report_for_import_server.sjs b/dom/security/test/csp/file_report_for_import_server.sjs new file mode 100644 index 0000000000..624c7e657b --- /dev/null +++ b/dom/security/test/csp/file_report_for_import_server.sjs @@ -0,0 +1,50 @@ +// Custom *.sjs file specifically for the needs of Bug: +// Bug 1048048 - CSP violation report not sent for @import + +const CC = Components.Constructor; +const BinaryInputStream = CC( + "@mozilla.org/binaryinputstream;1", + "nsIBinaryInputStream", + "setInputStream" +); + +function handleRequest(request, response) { + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/html", false); + var queryString = request.queryString; + + // (1) lets process the queryresult request async and + // wait till we have received the image request. + if (queryString === "queryresult") { + response.processAsync(); + setObjectState("queryResult", response); + return; + } + + // (2) handle the csp-report and return the JSON back to + // the testfile using the afore stored xml request in (1). + if (queryString === "report") { + getObjectState("queryResult", function (queryResponse) { + if (!queryResponse) { + return; + } + + // send the report back to the XML request for verification + var report = new BinaryInputStream(request.bodyInputStream); + var avail; + var bytes = []; + while ((avail = report.available()) > 0) { + Array.prototype.push.apply(bytes, report.readByteArray(avail)); + } + var data = String.fromCharCode.apply(null, bytes); + queryResponse.bodyOutputStream.write(data, data.length); + queryResponse.finish(); + }); + return; + } + + // we should not get here ever, but just in case return + // something unexpected. + response.write("doh!"); +} diff --git a/dom/security/test/csp/file_report_uri_missing_in_report_only_header.html b/dom/security/test/csp/file_report_uri_missing_in_report_only_header.html new file mode 100644 index 0000000000..e69de29bb2 diff --git a/dom/security/test/csp/file_report_uri_missing_in_report_only_header.html^headers^ b/dom/security/test/csp/file_report_uri_missing_in_report_only_header.html^headers^ new file mode 100644 index 0000000000..3f2fdfe9e6 --- /dev/null +++ b/dom/security/test/csp/file_report_uri_missing_in_report_only_header.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy-Report-Only: default-src 'self'; diff --git a/dom/security/test/csp/file_ro_ignore_xfo.html b/dom/security/test/csp/file_ro_ignore_xfo.html new file mode 100644 index 0000000000..85e7f0092c --- /dev/null +++ b/dom/security/test/csp/file_ro_ignore_xfo.html @@ -0,0 +1,10 @@ + + + + + Bug 1024557: Ignore x-frame-options if CSP with frame-ancestors exists + + +
Ignoring XFO because of CSP_RO
+ + \ No newline at end of file diff --git a/dom/security/test/csp/file_ro_ignore_xfo.html^headers^ b/dom/security/test/csp/file_ro_ignore_xfo.html^headers^ new file mode 100644 index 0000000000..ab8366f061 --- /dev/null +++ b/dom/security/test/csp/file_ro_ignore_xfo.html^headers^ @@ -0,0 +1,3 @@ +Content-Security-Policy-Report-Only: frame-ancestors http://mochi.test:8888 +X-Frame-Options: deny +Cache-Control: no-cache diff --git a/dom/security/test/csp/file_sandbox_1.html b/dom/security/test/csp/file_sandbox_1.html new file mode 100644 index 0000000000..ce1e80c865 --- /dev/null +++ b/dom/security/test/csp/file_sandbox_1.html @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/dom/security/test/csp/file_sandbox_10.html b/dom/security/test/csp/file_sandbox_10.html new file mode 100644 index 0000000000..f934497eee --- /dev/null +++ b/dom/security/test/csp/file_sandbox_10.html @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/dom/security/test/csp/file_sandbox_11.html b/dom/security/test/csp/file_sandbox_11.html new file mode 100644 index 0000000000..087b5651a9 --- /dev/null +++ b/dom/security/test/csp/file_sandbox_11.html @@ -0,0 +1,25 @@ + + + + + + + I am sandboxed but with only inline "allow-scripts" + + + + + + + + + + diff --git a/dom/security/test/csp/file_sandbox_12.html b/dom/security/test/csp/file_sandbox_12.html new file mode 100644 index 0000000000..79631bd394 --- /dev/null +++ b/dom/security/test/csp/file_sandbox_12.html @@ -0,0 +1,40 @@ + + + + + + + + + + I am sandboxed but with "allow-same-origin" and allow-scripts" + + + + + + + + +
+ First name: + Last name: + +
+ + click me + + diff --git a/dom/security/test/csp/file_sandbox_13.html b/dom/security/test/csp/file_sandbox_13.html new file mode 100644 index 0000000000..96286db8d5 --- /dev/null +++ b/dom/security/test/csp/file_sandbox_13.html @@ -0,0 +1,25 @@ + + + + + + + I am sandboxed but with only inline "allow-scripts" + + + + + + + + + + diff --git a/dom/security/test/csp/file_sandbox_2.html b/dom/security/test/csp/file_sandbox_2.html new file mode 100644 index 0000000000..b37aa1bcef --- /dev/null +++ b/dom/security/test/csp/file_sandbox_2.html @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/dom/security/test/csp/file_sandbox_3.html b/dom/security/test/csp/file_sandbox_3.html new file mode 100644 index 0000000000..ba808e47d5 --- /dev/null +++ b/dom/security/test/csp/file_sandbox_3.html @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/dom/security/test/csp/file_sandbox_4.html b/dom/security/test/csp/file_sandbox_4.html new file mode 100644 index 0000000000..b2d4ed0940 --- /dev/null +++ b/dom/security/test/csp/file_sandbox_4.html @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/dom/security/test/csp/file_sandbox_5.html b/dom/security/test/csp/file_sandbox_5.html new file mode 100644 index 0000000000..c08849b689 --- /dev/null +++ b/dom/security/test/csp/file_sandbox_5.html @@ -0,0 +1,26 @@ + + + + + + + I am sandboxed but with only inline "allow-scripts" + + + + + + + + + + + diff --git a/dom/security/test/csp/file_sandbox_6.html b/dom/security/test/csp/file_sandbox_6.html new file mode 100644 index 0000000000..44705f4d2b --- /dev/null +++ b/dom/security/test/csp/file_sandbox_6.html @@ -0,0 +1,35 @@ + + + + + + + + + + I am sandboxed but with "allow-same-origin" and allow-scripts" + + + +
+ First name: + Last name: + +
+ + click me + + diff --git a/dom/security/test/csp/file_sandbox_7.html b/dom/security/test/csp/file_sandbox_7.html new file mode 100644 index 0000000000..3b249d4101 --- /dev/null +++ b/dom/security/test/csp/file_sandbox_7.html @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/dom/security/test/csp/file_sandbox_8.html b/dom/security/test/csp/file_sandbox_8.html new file mode 100644 index 0000000000..4f9cd89161 --- /dev/null +++ b/dom/security/test/csp/file_sandbox_8.html @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/dom/security/test/csp/file_sandbox_9.html b/dom/security/test/csp/file_sandbox_9.html new file mode 100644 index 0000000000..29ffc191cd --- /dev/null +++ b/dom/security/test/csp/file_sandbox_9.html @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/dom/security/test/csp/file_sandbox_allow_scripts.html b/dom/security/test/csp/file_sandbox_allow_scripts.html new file mode 100644 index 0000000000..faab9f0fc6 --- /dev/null +++ b/dom/security/test/csp/file_sandbox_allow_scripts.html @@ -0,0 +1,12 @@ + + + + + Bug 1396320: Fix CSP sandbox regression for allow-scripts + + + + + diff --git a/dom/security/test/csp/file_sandbox_allow_scripts.html^headers^ b/dom/security/test/csp/file_sandbox_allow_scripts.html^headers^ new file mode 100644 index 0000000000..4705ce9ded --- /dev/null +++ b/dom/security/test/csp/file_sandbox_allow_scripts.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: sandbox allow-scripts; diff --git a/dom/security/test/csp/file_sandbox_fail.js b/dom/security/test/csp/file_sandbox_fail.js new file mode 100644 index 0000000000..7f43927ddf --- /dev/null +++ b/dom/security/test/csp/file_sandbox_fail.js @@ -0,0 +1,7 @@ +function ok(result, desc) { + window.parent.postMessage({ ok: result, desc }, "*"); +} +ok( + false, + "documents sandboxed with allow-scripts should NOT be able to run " + + // have an inline script that reports back to the parent whether + // the script got loaded or not from within the sandboxed iframe. + "" + + "" + + ""; + + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/html", false); + response.setHeader("Content-Security-Policy", policy, false); + + response.write(html); +} diff --git a/dom/security/test/csp/file_script_template.html b/dom/security/test/csp/file_script_template.html new file mode 100644 index 0000000000..3819592912 --- /dev/null +++ b/dom/security/test/csp/file_script_template.html @@ -0,0 +1,16 @@ + + + + + + + + + + diff --git a/dom/security/test/csp/file_script_template.js b/dom/security/test/csp/file_script_template.js new file mode 100644 index 0000000000..d75869f763 --- /dev/null +++ b/dom/security/test/csp/file_script_template.js @@ -0,0 +1 @@ +// dummy *.js file diff --git a/dom/security/test/csp/file_self_none_as_hostname_confusion.html b/dom/security/test/csp/file_self_none_as_hostname_confusion.html new file mode 100644 index 0000000000..16196bb19f --- /dev/null +++ b/dom/security/test/csp/file_self_none_as_hostname_confusion.html @@ -0,0 +1,11 @@ + + + + + Bug 587377 - CSP keywords "'self'" and "'none'" are easy to confuse with host names "self" and "none" + + + + + diff --git a/dom/security/test/csp/file_self_none_as_hostname_confusion.html^headers^ b/dom/security/test/csp/file_self_none_as_hostname_confusion.html^headers^ new file mode 100644 index 0000000000..26af7ed9b5 --- /dev/null +++ b/dom/security/test/csp/file_self_none_as_hostname_confusion.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: default-src 'self' SELF; diff --git a/dom/security/test/csp/file_sendbeacon.html b/dom/security/test/csp/file_sendbeacon.html new file mode 100644 index 0000000000..13202c65ff --- /dev/null +++ b/dom/security/test/csp/file_sendbeacon.html @@ -0,0 +1,21 @@ + + + + + + Bug 1234813 - sendBeacon should not throw if blocked by Content Policy + + + + + + + diff --git a/dom/security/test/csp/file_service_worker.html b/dom/security/test/csp/file_service_worker.html new file mode 100644 index 0000000000..b819946983 --- /dev/null +++ b/dom/security/test/csp/file_service_worker.html @@ -0,0 +1,21 @@ + + + + Bug 1208559 - ServiceWorker registration not governed by CSP + + + + + diff --git a/dom/security/test/csp/file_service_worker.js b/dom/security/test/csp/file_service_worker.js new file mode 100644 index 0000000000..1bf583f4cc --- /dev/null +++ b/dom/security/test/csp/file_service_worker.js @@ -0,0 +1 @@ +dump("service workers: hello world"); diff --git a/dom/security/test/csp/file_spawn_service_worker.js b/dom/security/test/csp/file_spawn_service_worker.js new file mode 100644 index 0000000000..b262fa10a3 --- /dev/null +++ b/dom/security/test/csp/file_spawn_service_worker.js @@ -0,0 +1 @@ +// dummy file diff --git a/dom/security/test/csp/file_spawn_shared_worker.js b/dom/security/test/csp/file_spawn_shared_worker.js new file mode 100644 index 0000000000..e4f53b9ce1 --- /dev/null +++ b/dom/security/test/csp/file_spawn_shared_worker.js @@ -0,0 +1,7 @@ +onconnect = function (e) { + var port = e.ports[0]; + port.addEventListener("message", function (e) { + port.postMessage("shared worker is executing"); + }); + port.start(); +}; diff --git a/dom/security/test/csp/file_spawn_worker.js b/dom/security/test/csp/file_spawn_worker.js new file mode 100644 index 0000000000..acde7408c1 --- /dev/null +++ b/dom/security/test/csp/file_spawn_worker.js @@ -0,0 +1 @@ +postMessage("worker is executing"); diff --git a/dom/security/test/csp/file_strict_dynamic.js b/dom/security/test/csp/file_strict_dynamic.js new file mode 100644 index 0000000000..09286d42e9 --- /dev/null +++ b/dom/security/test/csp/file_strict_dynamic.js @@ -0,0 +1 @@ +document.getElementById("testdiv").innerHTML = "allowed"; diff --git a/dom/security/test/csp/file_strict_dynamic_default_src.html b/dom/security/test/csp/file_strict_dynamic_default_src.html new file mode 100644 index 0000000000..0ea79e2a96 --- /dev/null +++ b/dom/security/test/csp/file_strict_dynamic_default_src.html @@ -0,0 +1,20 @@ + + + + Bug 1299483 - CSP: Implement 'strict-dynamic' + + + +
blocked
+ + + + + + + diff --git a/dom/security/test/csp/file_strict_dynamic_default_src.js b/dom/security/test/csp/file_strict_dynamic_default_src.js new file mode 100644 index 0000000000..09286d42e9 --- /dev/null +++ b/dom/security/test/csp/file_strict_dynamic_default_src.js @@ -0,0 +1 @@ +document.getElementById("testdiv").innerHTML = "allowed"; diff --git a/dom/security/test/csp/file_strict_dynamic_js_url.html b/dom/security/test/csp/file_strict_dynamic_js_url.html new file mode 100644 index 0000000000..bd53b0adb2 --- /dev/null +++ b/dom/security/test/csp/file_strict_dynamic_js_url.html @@ -0,0 +1,15 @@ + + + + Bug 1316826 - 'strict-dynamic' blocking DOM event handlers + + +
blocked
+ +click me + + + + diff --git a/dom/security/test/csp/file_strict_dynamic_non_parser_inserted.html b/dom/security/test/csp/file_strict_dynamic_non_parser_inserted.html new file mode 100644 index 0000000000..c51fefd72e --- /dev/null +++ b/dom/security/test/csp/file_strict_dynamic_non_parser_inserted.html @@ -0,0 +1,17 @@ + + + + Bug 1299483 - CSP: Implement 'strict-dynamic' + + +
blocked
+ + + + + diff --git a/dom/security/test/csp/file_strict_dynamic_non_parser_inserted_inline.html b/dom/security/test/csp/file_strict_dynamic_non_parser_inserted_inline.html new file mode 100644 index 0000000000..10a0f32e4b --- /dev/null +++ b/dom/security/test/csp/file_strict_dynamic_non_parser_inserted_inline.html @@ -0,0 +1,16 @@ + + + + Bug 1299483 - CSP: Implement 'strict-dynamic' + + +
blocked
+ + + + + diff --git a/dom/security/test/csp/file_strict_dynamic_parser_inserted_doc_write.html b/dom/security/test/csp/file_strict_dynamic_parser_inserted_doc_write.html new file mode 100644 index 0000000000..2a3a7d4998 --- /dev/null +++ b/dom/security/test/csp/file_strict_dynamic_parser_inserted_doc_write.html @@ -0,0 +1,15 @@ + + + + Bug 1299483 - CSP: Implement 'strict-dynamic' + + +
blocked
+ + + + + diff --git a/dom/security/test/csp/file_strict_dynamic_parser_inserted_doc_write_correct_nonce.html b/dom/security/test/csp/file_strict_dynamic_parser_inserted_doc_write_correct_nonce.html new file mode 100644 index 0000000000..9938ef2dcd --- /dev/null +++ b/dom/security/test/csp/file_strict_dynamic_parser_inserted_doc_write_correct_nonce.html @@ -0,0 +1,15 @@ + + + + Bug 1299483 - CSP: Implement 'strict-dynamic' + + +
blocked
+ + + + + diff --git a/dom/security/test/csp/file_strict_dynamic_script_events.html b/dom/security/test/csp/file_strict_dynamic_script_events.html new file mode 100644 index 0000000000..0889583821 --- /dev/null +++ b/dom/security/test/csp/file_strict_dynamic_script_events.html @@ -0,0 +1,14 @@ + + + + Bug 1316826 - 'strict-dynamic' blocking DOM event handlers + + +
blocked
+ + + + + diff --git a/dom/security/test/csp/file_strict_dynamic_script_events_marquee.html b/dom/security/test/csp/file_strict_dynamic_script_events_marquee.html new file mode 100644 index 0000000000..701ef32269 --- /dev/null +++ b/dom/security/test/csp/file_strict_dynamic_script_events_marquee.html @@ -0,0 +1,14 @@ + + + + Bug 1316826 - 'strict-dynamic' blocking DOM event handlers + + +
blocked
+ + + Bug 1316826 + + + + diff --git a/dom/security/test/csp/file_strict_dynamic_script_extern.html b/dom/security/test/csp/file_strict_dynamic_script_extern.html new file mode 100644 index 0000000000..94b6aefb19 --- /dev/null +++ b/dom/security/test/csp/file_strict_dynamic_script_extern.html @@ -0,0 +1,10 @@ + + + + Bug 1299483 - CSP: Implement 'strict-dynamic' + + +
blocked
+ + + diff --git a/dom/security/test/csp/file_strict_dynamic_script_inline.html b/dom/security/test/csp/file_strict_dynamic_script_inline.html new file mode 100644 index 0000000000..d17a58f279 --- /dev/null +++ b/dom/security/test/csp/file_strict_dynamic_script_inline.html @@ -0,0 +1,14 @@ + + + + Bug 1299483 - CSP: Implement 'strict-dynamic' + + +
blocked
+ + + + + diff --git a/dom/security/test/csp/file_strict_dynamic_unsafe_eval.html b/dom/security/test/csp/file_strict_dynamic_unsafe_eval.html new file mode 100644 index 0000000000..4f54015aa8 --- /dev/null +++ b/dom/security/test/csp/file_strict_dynamic_unsafe_eval.html @@ -0,0 +1,15 @@ + + + + Bug 1299483 - CSP: Implement 'strict-dynamic' + + +
blocked
+ + + + + diff --git a/dom/security/test/csp/file_subframe_run_js_if_allowed.html b/dom/security/test/csp/file_subframe_run_js_if_allowed.html new file mode 100644 index 0000000000..3ba970ce84 --- /dev/null +++ b/dom/security/test/csp/file_subframe_run_js_if_allowed.html @@ -0,0 +1,13 @@ + + + +click + + diff --git a/dom/security/test/csp/file_subframe_run_js_if_allowed.html^headers^ b/dom/security/test/csp/file_subframe_run_js_if_allowed.html^headers^ new file mode 100644 index 0000000000..233b359310 --- /dev/null +++ b/dom/security/test/csp/file_subframe_run_js_if_allowed.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: default-src *; script-src 'unsafe-inline' diff --git a/dom/security/test/csp/file_svg_inline_style_base.html b/dom/security/test/csp/file_svg_inline_style_base.html new file mode 100644 index 0000000000..4d7ce0cd6e --- /dev/null +++ b/dom/security/test/csp/file_svg_inline_style_base.html @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/dom/security/test/csp/file_svg_inline_style_csp.html b/dom/security/test/csp/file_svg_inline_style_csp.html new file mode 100644 index 0000000000..040ee02e19 --- /dev/null +++ b/dom/security/test/csp/file_svg_inline_style_csp.html @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/dom/security/test/csp/file_svg_inline_style_server.sjs b/dom/security/test/csp/file_svg_inline_style_server.sjs new file mode 100644 index 0000000000..6073f36f62 --- /dev/null +++ b/dom/security/test/csp/file_svg_inline_style_server.sjs @@ -0,0 +1,43 @@ +"use strict"; + +const SVG_IMG = ` + + + `; + +const SVG_IMG_NO_INLINE_STYLE = ` + + `; + +function handleRequest(request, response) { + const query = request.queryString; + + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "image/svg+xml", false); + + if (query.includes("svg_inline_style_csp")) { + response.setHeader("Content-Security-Policy", "default-src 'none'", false); + response.write(SVG_IMG); + return; + } + + if (query.includes("svg_inline_style_nocsp")) { + response.write(SVG_IMG); + return; + } + + if (query.includes("svg_no_inline_style")) { + response.write(SVG_IMG_NO_INLINE_STYLE); + return; + } + + // we should never get here, but just in case + // return something unexpected + response.write("do'h"); +} diff --git a/dom/security/test/csp/file_svg_srcset_inline_style_base.html b/dom/security/test/csp/file_svg_srcset_inline_style_base.html new file mode 100644 index 0000000000..1754c557f0 --- /dev/null +++ b/dom/security/test/csp/file_svg_srcset_inline_style_base.html @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/dom/security/test/csp/file_svg_srcset_inline_style_csp.html b/dom/security/test/csp/file_svg_srcset_inline_style_csp.html new file mode 100644 index 0000000000..418d714882 --- /dev/null +++ b/dom/security/test/csp/file_svg_srcset_inline_style_csp.html @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/dom/security/test/csp/file_test_browser_bookmarklets.html b/dom/security/test/csp/file_test_browser_bookmarklets.html new file mode 100644 index 0000000000..cb12e4efd0 --- /dev/null +++ b/dom/security/test/csp/file_test_browser_bookmarklets.html @@ -0,0 +1,12 @@ + + + + + + + Document + + +

Test-Document

+ + \ No newline at end of file diff --git a/dom/security/test/csp/file_test_browser_bookmarklets.html^headers^ b/dom/security/test/csp/file_test_browser_bookmarklets.html^headers^ new file mode 100644 index 0000000000..e138f234fb --- /dev/null +++ b/dom/security/test/csp/file_test_browser_bookmarklets.html^headers^ @@ -0,0 +1,2 @@ +Content-Security-Policy: script-src 'none' +Cache-Control: no-cache diff --git a/dom/security/test/csp/file_testserver.sjs b/dom/security/test/csp/file_testserver.sjs new file mode 100644 index 0000000000..77f9562218 --- /dev/null +++ b/dom/security/test/csp/file_testserver.sjs @@ -0,0 +1,66 @@ +// SJS file for CSP mochitests +"use strict"; +const { NetUtil } = ChromeUtils.importESModule( + "resource://gre/modules/NetUtil.sys.mjs" +); + +function loadHTMLFromFile(path) { + // Load the HTML to return in the response from file. + // Since it's relative to the cwd of the test runner, we start there and + // append to get to the actual path of the file. + const testHTMLFile = Cc["@mozilla.org/file/directory_service;1"] + .getService(Ci.nsIProperties) + .get("CurWorkD", Ci.nsIFile); + + const testHTMLFileStream = Cc[ + "@mozilla.org/network/file-input-stream;1" + ].createInstance(Ci.nsIFileInputStream); + + path + .split("/") + .filter(path => path) + .reduce((file, path) => { + testHTMLFile.append(path); + return testHTMLFile; + }, testHTMLFile); + testHTMLFileStream.init(testHTMLFile, -1, 0, 0); + const isAvailable = testHTMLFileStream.available(); + return NetUtil.readInputStreamToString(testHTMLFileStream, isAvailable); +} + +function handleRequest(request, response) { + const query = new URLSearchParams(request.queryString); + + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + // Deliver the CSP policy encoded in the URL + if (query.has("csp")) { + response.setHeader("Content-Security-Policy", query.get("csp"), false); + } + + // Deliver the CSP report-only policy encoded in the URI + if (query.has("cspRO")) { + response.setHeader( + "Content-Security-Policy-Report-Only", + query.get("cspRO"), + false + ); + } + + // Deliver the CORS header in the URL + if (query.has("cors")) { + response.setHeader("Access-Control-Allow-Origin", query.get("cors"), false); + } + + // Send HTML to test allowed/blocked behaviors + let type = "text/html"; + if (query.has("type")) { + type = query.get("type"); + } + + response.setHeader("Content-Type", type, false); + if (query.has("file")) { + response.write(loadHTMLFromFile(query.get("file"))); + } +} diff --git a/dom/security/test/csp/file_uir_top_nav.html b/dom/security/test/csp/file_uir_top_nav.html new file mode 100644 index 0000000000..28263e9db7 --- /dev/null +++ b/dom/security/test/csp/file_uir_top_nav.html @@ -0,0 +1,17 @@ + + + + + + + + + diff --git a/dom/security/test/csp/file_uir_top_nav_dummy.html b/dom/security/test/csp/file_uir_top_nav_dummy.html new file mode 100644 index 0000000000..65762f1c71 --- /dev/null +++ b/dom/security/test/csp/file_uir_top_nav_dummy.html @@ -0,0 +1,12 @@ + + + +just a dummy page to check uir applies to top level navigations + + + diff --git a/dom/security/test/csp/file_upgrade_insecure.html b/dom/security/test/csp/file_upgrade_insecure.html new file mode 100644 index 0000000000..14aad3ebd6 --- /dev/null +++ b/dom/security/test/csp/file_upgrade_insecure.html @@ -0,0 +1,90 @@ + + + + + Bug 1139297 - Implement CSP upgrade-insecure-requests directive + + + + + + + + + + + + + + + + + + + + + + + + +
foo
+ + + + + + + + + + + + +
+ + +
+ + + + diff --git a/dom/security/test/csp/file_upgrade_insecure_cors.html b/dom/security/test/csp/file_upgrade_insecure_cors.html new file mode 100644 index 0000000000..e675c62e9f --- /dev/null +++ b/dom/security/test/csp/file_upgrade_insecure_cors.html @@ -0,0 +1,49 @@ + + + + + Bug 1139297 - Implement CSP upgrade-insecure-requests directive + + + + + + + diff --git a/dom/security/test/csp/file_upgrade_insecure_cors_server.sjs b/dom/security/test/csp/file_upgrade_insecure_cors_server.sjs new file mode 100644 index 0000000000..83957560c3 --- /dev/null +++ b/dom/security/test/csp/file_upgrade_insecure_cors_server.sjs @@ -0,0 +1,61 @@ +// Custom *.sjs file specifically for the needs of Bug: +// Bug 1139297 - Implement CSP upgrade-insecure-requests directive + +function handleRequest(request, response) { + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + // perform sanity check and make sure that all requests get upgraded to use https + if (request.scheme !== "https") { + response.write("request not https"); + return; + } + + var queryString = request.queryString; + + // TEST 1 + if (queryString === "test1") { + var newLocation = + "http://test1.example.com/tests/dom/security/test/csp/file_upgrade_insecure_cors_server.sjs?redir-test1"; + response.setStatusLine("1.1", 302, "Found"); + response.setHeader("Location", newLocation, false); + return; + } + if (queryString === "redir-test1") { + response.write("test1-no-cors-ok"); + return; + } + + // TEST 2 + if (queryString === "test2") { + var newLocation = + "http://test1.example.com:443/tests/dom/security/test/csp/file_upgrade_insecure_cors_server.sjs?redir-test2"; + response.setStatusLine("1.1", 302, "Found"); + response.setHeader("Location", newLocation, false); + return; + } + if (queryString === "redir-test2") { + response.write("test2-no-cors-diffport-ok"); + return; + } + + // TEST 3 + response.setHeader("Access-Control-Allow-Headers", "content-type", false); + response.setHeader("Access-Control-Allow-Methods", "POST, GET", false); + response.setHeader("Access-Control-Allow-Origin", "*", false); + + if (queryString === "test3") { + var newLocation = + "http://test1.example.com/tests/dom/security/test/csp/file_upgrade_insecure_cors_server.sjs?redir-test3"; + response.setStatusLine("1.1", 302, "Found"); + response.setHeader("Location", newLocation, false); + return; + } + if (queryString === "redir-test3") { + response.write("test3-cors-ok"); + return; + } + + // we should not get here, but just in case return something unexpected + response.write("d'oh"); +} diff --git a/dom/security/test/csp/file_upgrade_insecure_docwrite_iframe.sjs b/dom/security/test/csp/file_upgrade_insecure_docwrite_iframe.sjs new file mode 100644 index 0000000000..a7fb0a2176 --- /dev/null +++ b/dom/security/test/csp/file_upgrade_insecure_docwrite_iframe.sjs @@ -0,0 +1,55 @@ +// custom *.sjs for Bug 1273430 +// META CSP: upgrade-insecure-requests + +// important: the IFRAME_URL is *http* and needs to be upgraded to *https* by upgrade-insecure-requests +const IFRAME_URL = + "http://example.com/tests/dom/security/test/csp/file_upgrade_insecure_docwrite_iframe.sjs?docwriteframe"; + +const TEST_FRAME = + ` + + + TEST_FRAME + + + + + + `; + +// doc.write(iframe) sends a post message to the parent indicating the current +// location so the parent can make sure the request was upgraded to *https*. +const DOC_WRITE_FRAME = ` + + + DOC_WRITE_FRAME + + + + `; + +function handleRequest(request, response) { + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/html", false); + + var queryString = request.queryString; + + if (queryString === "testframe") { + response.write(TEST_FRAME); + return; + } + + if (queryString === "docwriteframe") { + response.write(DOC_WRITE_FRAME); + return; + } + + // we should never get here, but just in case + // return something unexpected + response.write("do'h"); +} diff --git a/dom/security/test/csp/file_upgrade_insecure_loopback.html b/dom/security/test/csp/file_upgrade_insecure_loopback.html new file mode 100644 index 0000000000..b824604b6e --- /dev/null +++ b/dom/security/test/csp/file_upgrade_insecure_loopback.html @@ -0,0 +1,25 @@ + + + + + Bug 1447784 - Implement CSP upgrade-insecure-requests directive + + + + + + + diff --git a/dom/security/test/csp/file_upgrade_insecure_loopback_form.html b/dom/security/test/csp/file_upgrade_insecure_loopback_form.html new file mode 100644 index 0000000000..ed6b3b8542 --- /dev/null +++ b/dom/security/test/csp/file_upgrade_insecure_loopback_form.html @@ -0,0 +1,17 @@ + + + + + Bug 1661423 - don't apply upgrade-insecure-requests on form submissions to localhost + + + +
+ +
> + + + diff --git a/dom/security/test/csp/file_upgrade_insecure_loopback_server.sjs b/dom/security/test/csp/file_upgrade_insecure_loopback_server.sjs new file mode 100644 index 0000000000..ff7931a1d4 --- /dev/null +++ b/dom/security/test/csp/file_upgrade_insecure_loopback_server.sjs @@ -0,0 +1,22 @@ +// Custom *.sjs file specifically for the needs of Bug: +// Bug 1447784 - Implement CSP upgrade-insecure-requests directive + +function handleRequest(request, response) { + response.setHeader("Access-Control-Allow-Headers", "content-type", false); + response.setHeader("Access-Control-Allow-Methods", "GET", false); + response.setHeader("Access-Control-Allow-Origin", "*", false); + + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + // perform sanity check and make sure that all requests get upgraded to use https + if (request.scheme !== "https") { + response.write("request-not-https"); + return; + } else { + response.write("request-is-https"); + } + + // we should not get here, but just in case return something unexpected + response.write("d'oh"); +} diff --git a/dom/security/test/csp/file_upgrade_insecure_meta.html b/dom/security/test/csp/file_upgrade_insecure_meta.html new file mode 100644 index 0000000000..3509e5c6fd --- /dev/null +++ b/dom/security/test/csp/file_upgrade_insecure_meta.html @@ -0,0 +1,86 @@ + + + + + + Bug 1139297 - Implement CSP upgrade-insecure-requests directive + + + + + + + + + + + + + + + + + + + + + + + + +
foo
+ + + + + + + + + + + + +
+ + +
+ + + + diff --git a/dom/security/test/csp/file_upgrade_insecure_navigation.sjs b/dom/security/test/csp/file_upgrade_insecure_navigation.sjs new file mode 100644 index 0000000000..46473db0ac --- /dev/null +++ b/dom/security/test/csp/file_upgrade_insecure_navigation.sjs @@ -0,0 +1,78 @@ +// Custom *.sjs file specifically for the needs of +// https://bugzilla.mozilla.org/show_bug.cgi?id=1271173 + +"use strict"; + +const TEST_NAVIGATIONAL_UPGRADE = ` + + + + + clickme + + + `; + +const FRAME_NAV = ` + + + + + + + `; + +const DOC_NAV = ` + + + + + + + `; + +function handleRequest(request, response) { + const query = new URLSearchParams(request.queryString); + + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/html", false); + if (query.get("csp")) { + response.setHeader("Content-Security-Policy", query.get("csp"), false); + } + + if (query.get("action") === "perform_navigation") { + response.write(TEST_NAVIGATIONAL_UPGRADE); + return; + } + + if (query.get("action") === "framenav") { + response.write(FRAME_NAV); + return; + } + + if (query.get("action") === "docnav") { + response.write(DOC_NAV); + return; + } + + // we should never get here, but just in case + // return something unexpected + response.write("do'h"); +} diff --git a/dom/security/test/csp/file_upgrade_insecure_navigation_redirect.sjs b/dom/security/test/csp/file_upgrade_insecure_navigation_redirect.sjs new file mode 100644 index 0000000000..3f7f8158e0 --- /dev/null +++ b/dom/security/test/csp/file_upgrade_insecure_navigation_redirect.sjs @@ -0,0 +1,50 @@ +"use strict"; + +const FINAL_DOCUMENT = ` + + + final document + + + `; + +function handleRequest(request, response) { + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/html", false); + + const query = request.queryString; + + if (query === "same_origin_redirect") { + let newLocation = + "http://example.com/tests/dom/security/test/csp/file_upgrade_insecure_navigation_redirect.sjs?finaldoc_same_origin_redirect"; + response.setStatusLine("1.1", 302, "Found"); + response.setHeader("Location", newLocation, false); + return; + } + + if (query === "cross_origin_redirect") { + let newLocation = + "http://test1.example.com/tests/dom/security/test/csp/file_upgrade_insecure_navigation_redirect.sjs?finaldoc_cross_origin_redirect"; + response.setStatusLine("1.1", 302, "Found"); + response.setHeader("Location", newLocation, false); + return; + } + + if ( + query === "finaldoc_same_origin_redirect" || + query === "finaldoc_cross_origin_redirect" + ) { + response.write(FINAL_DOCUMENT); + return; + } + + // we should never get here, but just in case + // return something unexpected + response.write("do'h"); +} diff --git a/dom/security/test/csp/file_upgrade_insecure_navigation_redirect_cross_origin.html b/dom/security/test/csp/file_upgrade_insecure_navigation_redirect_cross_origin.html new file mode 100644 index 0000000000..dff2c9faf3 --- /dev/null +++ b/dom/security/test/csp/file_upgrade_insecure_navigation_redirect_cross_origin.html @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/dom/security/test/csp/file_upgrade_insecure_navigation_redirect_same_origin.html b/dom/security/test/csp/file_upgrade_insecure_navigation_redirect_same_origin.html new file mode 100644 index 0000000000..811850e08c --- /dev/null +++ b/dom/security/test/csp/file_upgrade_insecure_navigation_redirect_same_origin.html @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/dom/security/test/csp/file_upgrade_insecure_report_only.html b/dom/security/test/csp/file_upgrade_insecure_report_only.html new file mode 100644 index 0000000000..0c3c36493d --- /dev/null +++ b/dom/security/test/csp/file_upgrade_insecure_report_only.html @@ -0,0 +1,33 @@ + + + + + Bug 1832249 - Consider report-only flag when upgrading insecure requests + + + + + + + + diff --git a/dom/security/test/csp/file_upgrade_insecure_report_only_server.sjs b/dom/security/test/csp/file_upgrade_insecure_report_only_server.sjs new file mode 100644 index 0000000000..412d9b352e --- /dev/null +++ b/dom/security/test/csp/file_upgrade_insecure_report_only_server.sjs @@ -0,0 +1,114 @@ +// Custom *.sjs specifically for the needs of Bug 1832249 - Consider report-only flag when upgrading insecure requests + +const { NetUtil } = ChromeUtils.importESModule( + "resource://gre/modules/NetUtil.sys.mjs" +); + +// small red image +const IMG_BYTES = atob( + "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12" + + "P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" +); + +const POLICY_CSP = + "upgrade-insecure-requests; default-src https: 'unsafe-inline'"; +const POLICY_CSP_RO = + "default-src https: 'unsafe-inline'; upgrade-insecure-requests; report-uri https://example.com/tests/dom/security/test/csp/file_upgrade_insecure_report_only_server.sjs?report"; + +function loadHTMLFromFile(path) { + // Load the HTML to return in the response from file. + // Since it's relative to the cwd of the test runner, we start there and + // append to get to the actual path of the file. + var testHTMLFile = Cc["@mozilla.org/file/directory_service;1"] + .getService(Ci.nsIProperties) + .get("CurWorkD", Ci.nsIFile); + var dirs = path.split("/"); + for (var i = 0; i < dirs.length; i++) { + testHTMLFile.append(dirs[i]); + } + var testHTMLFileStream = Cc[ + "@mozilla.org/network/file-input-stream;1" + ].createInstance(Ci.nsIFileInputStream); + testHTMLFileStream.init(testHTMLFile, -1, 0, 0); + var testHTML = NetUtil.readInputStreamToString( + testHTMLFileStream, + testHTMLFileStream.available() + ); + return testHTML; +} + +function handleRequest(request, response) { + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + // (1) Store the query that will report back whether the violation report was + // received + if (request.queryString.startsWith("queryresult-")) { + let route = request.queryString.substring("queryresult-".length); + response.processAsync(); + setObjectState(`queryResult-${route}`, response); + return; + } + + // (2) We load a page using a report only CSP + if (request.queryString.endsWith("=true")) { + let route = request.queryString.split("=")[0]; + if (route === "enforce") { + response.setHeader("Content-Security-Policy", POLICY_CSP, false); + } + response.setHeader( + "Content-Security-Policy-Report-Only", + POLICY_CSP_RO + "-" + route, + false + ); + response.setHeader("Content-Type", "text/html", false); + response.write( + loadHTMLFromFile( + "tests/dom/security/test/csp/file_upgrade_insecure_report_only.html" + ) + ); + return; + } + + // (3a) Return the image back to the client if http and refuse if https for + // report only image + if (request.queryString.startsWith("img-")) { + let route = request.queryString.substring("img-".length); + if ( + (request.scheme === "http" && route === "reportonly") || + (request.scheme === "https" && route === "enforce") + ) { + response.setHeader("Content-Type", "image/png"); + response.write(IMG_BYTES); + return; + } else { + response.setStatusLine(metadata.httpVersion, 404, "NO"); + response.write("Aww, 404, I wanted a peanut."); + return; + } + } + + // (4) Once we receive the report send it to the client via the saved + // queryresult response object + if (request.queryString.startsWith("report-")) { + let route = request.queryString.substring("report-".length); + getObjectState(`queryResult-${route}`, function (queryResponse) { + if (!queryResponse) { + return; + } + queryResponse.setHeader("Content-Type", "application/json"); + queryResponse.write( + NetUtil.readInputStreamToString( + request.bodyInputStream, + request.bodyInputStream.available() + ) + ); + queryResponse.finish(); + }); + return; + } + + // we should never get here, but just in case ... + response.setHeader("Content-Type", "text/plain"); + response.write("doh!"); +} diff --git a/dom/security/test/csp/file_upgrade_insecure_reporting.html b/dom/security/test/csp/file_upgrade_insecure_reporting.html new file mode 100644 index 0000000000..c78e9a784d --- /dev/null +++ b/dom/security/test/csp/file_upgrade_insecure_reporting.html @@ -0,0 +1,23 @@ + + + + + Bug 1139297 - Implement CSP upgrade-insecure-requests directive + + + + + + + + + + diff --git a/dom/security/test/csp/file_upgrade_insecure_reporting_server.sjs b/dom/security/test/csp/file_upgrade_insecure_reporting_server.sjs new file mode 100644 index 0000000000..0d17288802 --- /dev/null +++ b/dom/security/test/csp/file_upgrade_insecure_reporting_server.sjs @@ -0,0 +1,89 @@ +// Custom *.sjs specifically for the needs of Bug +// Bug 1139297 - Implement CSP upgrade-insecure-requests directive + +const { NetUtil } = ChromeUtils.importESModule( + "resource://gre/modules/NetUtil.sys.mjs" +); + +// small red image +const IMG_BYTES = atob( + "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12" + + "P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" +); + +const REPORT_URI = + "https://example.com/tests/dom/security/test/csp/file_upgrade_insecure_reporting_server.sjs?report"; +const POLICY = "upgrade-insecure-requests; default-src https: 'unsafe-inline'"; +const POLICY_RO = + "default-src https: 'unsafe-inline'; report-uri " + REPORT_URI; + +function loadHTMLFromFile(path) { + // Load the HTML to return in the response from file. + // Since it's relative to the cwd of the test runner, we start there and + // append to get to the actual path of the file. + var testHTMLFile = Cc["@mozilla.org/file/directory_service;1"] + .getService(Ci.nsIProperties) + .get("CurWorkD", Ci.nsIFile); + var dirs = path.split("/"); + for (var i = 0; i < dirs.length; i++) { + testHTMLFile.append(dirs[i]); + } + var testHTMLFileStream = Cc[ + "@mozilla.org/network/file-input-stream;1" + ].createInstance(Ci.nsIFileInputStream); + testHTMLFileStream.init(testHTMLFile, -1, 0, 0); + var testHTML = NetUtil.readInputStreamToString( + testHTMLFileStream, + testHTMLFileStream.available() + ); + return testHTML; +} + +function handleRequest(request, response) { + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + // (1) Store the query that will report back whether the violation report was received + if (request.queryString == "queryresult") { + response.processAsync(); + setObjectState("queryResult", response); + return; + } + + // (2) We load a page using a CSP and a report only CSP + if (request.queryString == "toplevel") { + response.setHeader("Content-Security-Policy", POLICY, false); + response.setHeader("Content-Security-Policy-Report-Only", POLICY_RO, false); + response.setHeader("Content-Type", "text/html", false); + response.write( + loadHTMLFromFile( + "tests/dom/security/test/csp/file_upgrade_insecure_reporting.html" + ) + ); + return; + } + + // (3) Return the image back to the client + if (request.queryString == "img") { + response.setHeader("Content-Type", "image/png"); + response.write(IMG_BYTES); + return; + } + + // (4) Finally we receive the report, let's return the request from (1) + // signaling that we received the report correctly + if (request.queryString == "report") { + getObjectState("queryResult", function (queryResponse) { + if (!queryResponse) { + return; + } + queryResponse.write("report-ok"); + queryResponse.finish(); + }); + return; + } + + // we should never get here, but just in case ... + response.setHeader("Content-Type", "text/plain"); + response.write("doh!"); +} diff --git a/dom/security/test/csp/file_upgrade_insecure_server.sjs b/dom/security/test/csp/file_upgrade_insecure_server.sjs new file mode 100644 index 0000000000..05d027c078 --- /dev/null +++ b/dom/security/test/csp/file_upgrade_insecure_server.sjs @@ -0,0 +1,112 @@ +// Custom *.sjs file specifically for the needs of Bug: +// Bug 1139297 - Implement CSP upgrade-insecure-requests directive + +const TOTAL_EXPECTED_REQUESTS = 11; + +const IFRAME_CONTENT = + "" + + "" + + "" + + "Bug 1139297 - Implement CSP upgrade-insecure-requests directive" + + "" + + "" + + "" + + "" + + ""; + +const expectedQueries = [ + "script", + "style", + "img", + "iframe", + "form", + "xhr", + "media", + "object", + "font", + "img-redir", + "nested-img", +]; + +function handleRequest(request, response) { + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + var queryString = request.queryString; + + // initialize server variables and save the object state + // of the initial request, which returns async once the + // server has processed all requests. + if (queryString == "queryresult") { + setState("totaltests", TOTAL_EXPECTED_REQUESTS.toString()); + setState("receivedQueries", ""); + response.processAsync(); + setObjectState("queryResult", response); + return; + } + + // handle img redirect (https->http) + if (queryString == "redirect-image") { + var newLocation = + "http://example.com/tests/dom/security/test/csp/file_upgrade_insecure_server.sjs?img-redir"; + response.setStatusLine("1.1", 302, "Found"); + response.setHeader("Location", newLocation, false); + return; + } + + // just in case error handling for unexpected queries + if (expectedQueries.indexOf(queryString) == -1) { + response.write("doh!"); + return; + } + + // make sure all the requested queries are indeed https + queryString += request.scheme == "https" ? "-ok" : "-error"; + + var receivedQueries = getState("receivedQueries"); + + // images, scripts, etc. get queried twice, do not + // confuse the server by storing the preload as + // well as the actual load. If either the preload + // or the actual load is not https, then we would + // append "-error" in the array and the test would + // fail at the end. + if (receivedQueries.includes(queryString)) { + return; + } + + // append the result to the total query string array + if (receivedQueries != "") { + receivedQueries += ","; + } + receivedQueries += queryString; + setState("receivedQueries", receivedQueries); + + // keep track of how many more requests the server + // is expecting + var totaltests = parseInt(getState("totaltests")); + totaltests -= 1; + setState("totaltests", totaltests.toString()); + + // return content (img) for the nested iframe to test + // that subresource requests within nested contexts + // get upgraded as well. We also have to return + // the iframe context in case of an error so we + // can test both, using upgrade-insecure as well + // as the base case of not using upgrade-insecure. + if (queryString == "iframe-ok" || queryString == "iframe-error") { + response.write(IFRAME_CONTENT); + } + + // if we have received all the requests, we return + // the result back. + if (totaltests == 0) { + getObjectState("queryResult", function (queryResponse) { + if (!queryResponse) { + return; + } + var receivedQueries = getState("receivedQueries"); + queryResponse.write(receivedQueries); + queryResponse.finish(); + }); + } +} diff --git a/dom/security/test/csp/file_upgrade_insecure_wsh.py b/dom/security/test/csp/file_upgrade_insecure_wsh.py new file mode 100644 index 0000000000..b7159c742b --- /dev/null +++ b/dom/security/test/csp/file_upgrade_insecure_wsh.py @@ -0,0 +1,6 @@ +def web_socket_do_extra_handshake(request): + pass + + +def web_socket_transfer_data(request): + pass diff --git a/dom/security/test/csp/file_web_manifest.html b/dom/security/test/csp/file_web_manifest.html new file mode 100644 index 0000000000..0f6a67460e --- /dev/null +++ b/dom/security/test/csp/file_web_manifest.html @@ -0,0 +1,6 @@ + + + + + +

Support Page for Web Manifest Tests

\ No newline at end of file diff --git a/dom/security/test/csp/file_web_manifest.json b/dom/security/test/csp/file_web_manifest.json new file mode 100644 index 0000000000..eb88b50445 --- /dev/null +++ b/dom/security/test/csp/file_web_manifest.json @@ -0,0 +1 @@ +{ "name": "loaded" } diff --git a/dom/security/test/csp/file_web_manifest.json^headers^ b/dom/security/test/csp/file_web_manifest.json^headers^ new file mode 100644 index 0000000000..e0e00c4be0 --- /dev/null +++ b/dom/security/test/csp/file_web_manifest.json^headers^ @@ -0,0 +1 @@ +Access-Control-Allow-Origin: http://example.org \ No newline at end of file diff --git a/dom/security/test/csp/file_web_manifest_https.html b/dom/security/test/csp/file_web_manifest_https.html new file mode 100644 index 0000000000..b0ff9ef853 --- /dev/null +++ b/dom/security/test/csp/file_web_manifest_https.html @@ -0,0 +1,4 @@ + + + +

Support Page for Web Manifest Tests

\ No newline at end of file diff --git a/dom/security/test/csp/file_web_manifest_https.json b/dom/security/test/csp/file_web_manifest_https.json new file mode 100644 index 0000000000..eb88b50445 --- /dev/null +++ b/dom/security/test/csp/file_web_manifest_https.json @@ -0,0 +1 @@ +{ "name": "loaded" } diff --git a/dom/security/test/csp/file_web_manifest_mixed_content.html b/dom/security/test/csp/file_web_manifest_mixed_content.html new file mode 100644 index 0000000000..55f17c0f92 --- /dev/null +++ b/dom/security/test/csp/file_web_manifest_mixed_content.html @@ -0,0 +1,9 @@ + + + + + +

Support Page for Web Manifest Tests

+

Used to try to load a resource over an insecure connection to trigger mixed content blocking.

\ No newline at end of file diff --git a/dom/security/test/csp/file_web_manifest_remote.html b/dom/security/test/csp/file_web_manifest_remote.html new file mode 100644 index 0000000000..7ecf8eec43 --- /dev/null +++ b/dom/security/test/csp/file_web_manifest_remote.html @@ -0,0 +1,8 @@ + + + + +

Support Page for Web Manifest Tests

+

Loads a manifest from mochi.test:8888 with CORS set to "*".

\ No newline at end of file diff --git a/dom/security/test/csp/file_websocket_csp_upgrade.html b/dom/security/test/csp/file_websocket_csp_upgrade.html new file mode 100644 index 0000000000..9302a6e637 --- /dev/null +++ b/dom/security/test/csp/file_websocket_csp_upgrade.html @@ -0,0 +1,20 @@ + + + + + Bug 1729897: Allow unsecure websocket from localhost page with CSP: upgrade-insecure + + + + + + diff --git a/dom/security/test/csp/file_websocket_explicit.html b/dom/security/test/csp/file_websocket_explicit.html new file mode 100644 index 0000000000..51462ab741 --- /dev/null +++ b/dom/security/test/csp/file_websocket_explicit.html @@ -0,0 +1,31 @@ + + + + + Bug 1345615: Allow websocket schemes when using 'self' in CSP + + + + + + diff --git a/dom/security/test/csp/file_websocket_self.html b/dom/security/test/csp/file_websocket_self.html new file mode 100644 index 0000000000..3ff5f05580 --- /dev/null +++ b/dom/security/test/csp/file_websocket_self.html @@ -0,0 +1,31 @@ + + + + + Bug 1345615: Allow websocket schemes when using 'self' in CSP + + + + + + diff --git a/dom/security/test/csp/file_websocket_self_wsh.py b/dom/security/test/csp/file_websocket_self_wsh.py new file mode 100644 index 0000000000..eb45e224f3 --- /dev/null +++ b/dom/security/test/csp/file_websocket_self_wsh.py @@ -0,0 +1,6 @@ +def web_socket_do_extra_handshake(request): + pass + + +def web_socket_transfer_data(request): + pass diff --git a/dom/security/test/csp/file_win_open_blocked.html b/dom/security/test/csp/file_win_open_blocked.html new file mode 100644 index 0000000000..2d0828a872 --- /dev/null +++ b/dom/security/test/csp/file_win_open_blocked.html @@ -0,0 +1,3 @@ + diff --git a/dom/security/test/csp/file_windowwatcher_frameA.html b/dom/security/test/csp/file_windowwatcher_frameA.html new file mode 100644 index 0000000000..9e544142ce --- /dev/null +++ b/dom/security/test/csp/file_windowwatcher_frameA.html @@ -0,0 +1,17 @@ + + + +frame A
+ + + + + + + diff --git a/dom/security/test/csp/file_windowwatcher_subframeB.html b/dom/security/test/csp/file_windowwatcher_subframeB.html new file mode 100644 index 0000000000..e7ef422313 --- /dev/null +++ b/dom/security/test/csp/file_windowwatcher_subframeB.html @@ -0,0 +1,12 @@ + + + +subFrame B + + + + diff --git a/dom/security/test/csp/file_windowwatcher_subframeC.html b/dom/security/test/csp/file_windowwatcher_subframeC.html new file mode 100644 index 0000000000..b97c40432e --- /dev/null +++ b/dom/security/test/csp/file_windowwatcher_subframeC.html @@ -0,0 +1,9 @@ + + + + + + +subFrame C + + diff --git a/dom/security/test/csp/file_windowwatcher_subframeD.html b/dom/security/test/csp/file_windowwatcher_subframeD.html new file mode 100644 index 0000000000..2f778ea4cd --- /dev/null +++ b/dom/security/test/csp/file_windowwatcher_subframeD.html @@ -0,0 +1,6 @@ + + + +subFrame D + + diff --git a/dom/security/test/csp/file_windowwatcher_win_open.html b/dom/security/test/csp/file_windowwatcher_win_open.html new file mode 100644 index 0000000000..0237e49377 --- /dev/null +++ b/dom/security/test/csp/file_windowwatcher_win_open.html @@ -0,0 +1,15 @@ + + + +Opened Window
+ + + + diff --git a/dom/security/test/csp/file_worker_src.js b/dom/security/test/csp/file_worker_src.js new file mode 100644 index 0000000000..ce60379fef --- /dev/null +++ b/dom/security/test/csp/file_worker_src.js @@ -0,0 +1,73 @@ +var mySharedWorker = new SharedWorker("file_spawn_shared_worker.js"); +mySharedWorker.port.onmessage = function (ev) { + parent.postMessage( + { + result: "shared-worker-allowed", + href: document.location.href, + }, + "*" + ); + mySharedWorker.port.close(); +}; +mySharedWorker.onerror = function (evt) { + evt.preventDefault(); + parent.postMessage( + { + result: "shared-worker-blocked", + href: document.location.href, + }, + "*" + ); + mySharedWorker.port.close(); +}; +mySharedWorker.port.start(); +mySharedWorker.port.postMessage("foo"); + +// -------------------------------------------- + +let myWorker = new Worker("file_spawn_worker.js"); +myWorker.onmessage = function (event) { + parent.postMessage( + { + result: "worker-allowed", + href: document.location.href, + }, + "*" + ); +}; +myWorker.onerror = function (event) { + parent.postMessage( + { + result: "worker-blocked", + href: document.location.href, + }, + "*" + ); +}; + +// -------------------------------------------- + +navigator.serviceWorker + .register("file_spawn_service_worker.js") + .then(function (reg) { + // registration worked + reg.unregister().then(function () { + parent.postMessage( + { + result: "service-worker-allowed", + href: document.location.href, + }, + "*" + ); + }); + }) + .catch(function (error) { + // registration failed + parent.postMessage( + { + result: "service-worker-blocked", + href: document.location.href, + }, + "*" + ); + }); diff --git a/dom/security/test/csp/file_worker_src_child_governs.html b/dom/security/test/csp/file_worker_src_child_governs.html new file mode 100644 index 0000000000..ca8a683aac --- /dev/null +++ b/dom/security/test/csp/file_worker_src_child_governs.html @@ -0,0 +1,9 @@ + + + + "; + + + + + diff --git a/dom/security/test/csp/file_worker_src_script_governs.html b/dom/security/test/csp/file_worker_src_script_governs.html new file mode 100644 index 0000000000..0385fee57c --- /dev/null +++ b/dom/security/test/csp/file_worker_src_script_governs.html @@ -0,0 +1,9 @@ + + + + "; + + + + + diff --git a/dom/security/test/csp/file_worker_src_worker_governs.html b/dom/security/test/csp/file_worker_src_worker_governs.html new file mode 100644 index 0000000000..93c8f61225 --- /dev/null +++ b/dom/security/test/csp/file_worker_src_worker_governs.html @@ -0,0 +1,9 @@ + + + + "; + + + + + diff --git a/dom/security/test/csp/file_xslt_inherits_csp.xml b/dom/security/test/csp/file_xslt_inherits_csp.xml new file mode 100644 index 0000000000..a6d99c3081 --- /dev/null +++ b/dom/security/test/csp/file_xslt_inherits_csp.xml @@ -0,0 +1,6 @@ + + + + + This is some Title + diff --git a/dom/security/test/csp/file_xslt_inherits_csp.xml^headers^ b/dom/security/test/csp/file_xslt_inherits_csp.xml^headers^ new file mode 100644 index 0000000000..635af0a4d9 --- /dev/null +++ b/dom/security/test/csp/file_xslt_inherits_csp.xml^headers^ @@ -0,0 +1,2 @@ +Content-Security-Policy: script-src 'self' +Cache-Control: no-cache diff --git a/dom/security/test/csp/file_xslt_inherits_csp.xsl b/dom/security/test/csp/file_xslt_inherits_csp.xsl new file mode 100644 index 0000000000..82a4b0ad97 --- /dev/null +++ b/dom/security/test/csp/file_xslt_inherits_csp.xsl @@ -0,0 +1,26 @@ + + + + + + + + <xsl:value-of select="$title"/> + + + + +

+ Below is some inline JavaScript generating some red text. +

+ +

+ + + link with lineOnClick + + + + diff --git a/dom/security/test/csp/main_csp_worker.html b/dom/security/test/csp/main_csp_worker.html new file mode 100644 index 0000000000..8957e3fd25 --- /dev/null +++ b/dom/security/test/csp/main_csp_worker.html @@ -0,0 +1,439 @@ + + + + Bug 1475849: Test CSP worker inheritance + + + + + + + + + + diff --git a/dom/security/test/csp/main_csp_worker.html^headers^ b/dom/security/test/csp/main_csp_worker.html^headers^ new file mode 100644 index 0000000000..4597e01040 --- /dev/null +++ b/dom/security/test/csp/main_csp_worker.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: default-src 'self' blob: 'unsafe-inline' diff --git a/dom/security/test/csp/mochitest.toml b/dom/security/test/csp/mochitest.toml new file mode 100644 index 0000000000..8d8c6c31f5 --- /dev/null +++ b/dom/security/test/csp/mochitest.toml @@ -0,0 +1,821 @@ +[DEFAULT] +support-files = [ + "file_base_uri_server.sjs", + "file_blob_data_schemes.html", + "file_blob_uri_blocks_modals.html", + "file_blob_uri_blocks_modals.html^headers^", + "file_blob_top_nav_block_modals.html", + "file_blob_top_nav_block_modals.html^headers^", + "file_connect-src.html", + "file_connect-src-fetch.html", + "file_CSP.css", + "file_CSP.sjs", + "file_dummy_pixel.png", + "file_allow_https_schemes.html", + "file_bug663567.xsl", + "file_bug663567_allows.xml", + "file_bug663567_allows.xml^headers^", + "file_bug663567_blocks.xml", + "file_bug663567_blocks.xml^headers^", + "file_bug802872.html", + "file_bug802872.html^headers^", + "file_bug802872.js", + "file_bug802872.sjs", + "file_bug885433_allows.html", + "file_bug885433_allows.html^headers^", + "file_bug885433_blocks.html", + "file_bug885433_blocks.html^headers^", + "file_bug888172.html", + "file_bug888172.sjs", + "file_evalscript_main.js", + "file_evalscript_main_allowed.js", + "file_evalscript_main.html", + "file_evalscript_main.html^headers^", + "file_evalscript_main_allowed.html", + "file_evalscript_main_allowed.html^headers^", + "file_frameancestors_main.html", + "file_frameancestors_main.js", + "file_frameancestors.sjs", + "file_frameancestors_userpass.html", + "file_frameancestors_userpass_frame_a.html", + "file_frameancestors_userpass_frame_b.html", + "file_frameancestors_userpass_frame_c.html", + "file_frameancestors_userpass_frame_c.html^headers^", + "file_frameancestors_userpass_frame_d.html", + "file_frameancestors_userpass_frame_d.html^headers^", + "file_inlinescript.html", + "file_inlinestyle_main.html", + "file_inlinestyle_main.html^headers^", + "file_inlinestyle_main_allowed.html", + "file_inlinestyle_main_allowed.html^headers^", + "file_invalid_source_expression.html", + "file_main.html", + "file_main.html^headers^", + "file_main.js", + "file_web_manifest.html", + "file_web_manifest_remote.html", + "file_web_manifest_https.html", + "file_web_manifest.json", + "file_web_manifest.json^headers^", + "file_web_manifest_https.json", + "file_web_manifest_mixed_content.html", + "file_bug836922_npolicies.html", + "file_bug836922_npolicies.html^headers^", + "file_bug836922_npolicies_ro_violation.sjs", + "file_bug836922_npolicies_violation.sjs", + "file_bug886164.html", + "file_bug886164.html^headers^", + "file_bug886164_2.html", + "file_bug886164_2.html^headers^", + "file_bug886164_3.html", + "file_bug886164_3.html^headers^", + "file_bug886164_4.html", + "file_bug886164_4.html^headers^", + "file_bug886164_5.html", + "file_bug886164_5.html^headers^", + "file_bug886164_6.html", + "file_bug886164_6.html^headers^", + "file_redirects_main.html", + "file_redirects_page.sjs", + "file_redirects_resource.sjs", + "file_bug910139.sjs", + "file_bug910139.xml", + "file_bug910139.xsl", + "file_bug909029_star.html", + "file_bug909029_star.html^headers^", + "file_bug909029_none.html", + "file_bug909029_none.html^headers^", + "file_bug1229639.html", + "file_bug1229639.html^headers^", + "file_bug1312272.html", + "file_bug1312272.js", + "file_bug1312272.html^headers^", + "file_bug1452037.html", + "file_bug1505412.sjs", + "file_bug1505412_reporter.sjs", + "file_bug1505412_frame.html", + "file_bug1505412_frame.html^headers^", + "file_policyuri_regression_from_multipolicy.html", + "file_policyuri_regression_from_multipolicy.html^headers^", + "file_policyuri_regression_from_multipolicy_policy", + "file_nonce_source.html", + "file_nonce_source.html^headers^", + "file_nonce_redirects.html", + "file_nonce_redirector.sjs", + "file_bug941404.html", + "file_bug941404_xhr.html", + "file_bug941404_xhr.html^headers^", + "file_frame_ancestors_ro.html", + "file_frame_ancestors_ro.html^headers^", + "file_hash_source.html", + "file_dual_header_testserver.sjs", + "file_hash_source.html^headers^", + "file_scheme_relative_sources.js", + "file_scheme_relative_sources.sjs", + "file_ignore_unsafe_inline.html", + "file_ignore_unsafe_inline_multiple_policies_server.sjs", + "file_self_none_as_hostname_confusion.html", + "file_self_none_as_hostname_confusion.html^headers^", + "file_empty_directive.html", + "file_empty_directive.html^headers^", + "file_path_matching.html", + "file_path_matching_incl_query.html", + "file_path_matching.js", + "file_path_matching_redirect.html", + "file_path_matching_redirect_server.sjs", + "file_testserver.sjs", + "file_report_uri_missing_in_report_only_header.html", + "file_report_uri_missing_in_report_only_header.html^headers^", + "file_report.html", + "file_report_chromescript.js", + "file_redirect_content.sjs", + "file_redirect_report.sjs", + "file_subframe_run_js_if_allowed.html", + "file_subframe_run_js_if_allowed.html^headers^", + "file_leading_wildcard.html", + "file_multi_policy_injection_bypass.html", + "file_multi_policy_injection_bypass.html^headers^", + "file_multi_policy_injection_bypass_2.html", + "file_multi_policy_injection_bypass_2.html^headers^", + "file_null_baseuri.html", + "file_form-action.html", + "referrerdirective.sjs", + "file_upgrade_insecure.html", + "file_upgrade_insecure_meta.html", + "file_upgrade_insecure_server.sjs", + "file_upgrade_insecure_wsh.py", + "file_upgrade_insecure_reporting.html", + "file_upgrade_insecure_reporting_server.sjs", + "file_upgrade_insecure_cors.html", + "file_upgrade_insecure_cors_server.sjs", + "file_upgrade_insecure_loopback.html", + "file_upgrade_insecure_loopback_form.html", + "file_upgrade_insecure_loopback_server.sjs", + "file_report_for_import.css", + "file_report_for_import.html", + "file_report_for_import_server.sjs", + "file_service_worker.html", + "file_service_worker.js", + "file_child-src_iframe.html", + "file_child-src_inner_frame.html", + "file_child-src_worker.html", + "file_child-src_worker_data.html", + "file_child-src_worker-redirect.html", + "file_child-src_worker.js", + "file_child-src_service_worker.html", + "file_child-src_service_worker.js", + "file_child-src_shared_worker.html", + "file_child-src_shared_worker_data.html", + "file_child-src_shared_worker-redirect.html", + "file_child-src_shared_worker.js", + "file_redirect_worker.sjs", + "file_meta_element.html", + "file_meta_header_dual.sjs", + "file_docwrite_meta.html", + "file_doccomment_meta.html", + "file_docwrite_meta.css", + "file_docwrite_meta.js", + "file_multipart_testserver.sjs", + "file_fontloader.sjs", + "file_fontloader.woff", + "file_block_all_mcb.sjs", + "file_block_all_mixed_content_frame_navigation1.html", + "file_block_all_mixed_content_frame_navigation2.html", + "file_form_action_server.sjs", + "!/image/test/mochitest/blue.png", + "file_meta_whitespace_skipping.html", + "file_ping.html", + "test_iframe_sandbox_top_1.html^headers^", + "file_iframe_sandbox_document_write.html", + "file_sandbox_pass.js", + "file_sandbox_fail.js", + "file_sandbox_1.html", + "file_sandbox_2.html", + "file_sandbox_3.html", + "file_sandbox_4.html", + "file_sandbox_5.html", + "file_sandbox_6.html", + "file_sandbox_7.html", + "file_sandbox_8.html", + "file_sandbox_9.html", + "file_sandbox_10.html", + "file_sandbox_11.html", + "file_sandbox_12.html", + "file_sandbox_13.html", + "file_sendbeacon.html", + "file_upgrade_insecure_docwrite_iframe.sjs", + "file_data-uri_blocked.html", + "file_data-uri_blocked.html^headers^", + "file_strict_dynamic_js_url.html", + "file_strict_dynamic_script_events.html", + "file_strict_dynamic_script_events_marquee.html", + "file_strict_dynamic_script_inline.html", + "file_strict_dynamic_script_extern.html", + "file_strict_dynamic.js", + "file_strict_dynamic_parser_inserted_doc_write.html", + "file_strict_dynamic_parser_inserted_doc_write_correct_nonce.html", + "file_strict_dynamic_non_parser_inserted.html", + "file_strict_dynamic_non_parser_inserted_inline.html", + "file_strict_dynamic_unsafe_eval.html", + "file_strict_dynamic_default_src.html", + "file_strict_dynamic_default_src.js", + "file_upgrade_insecure_navigation.sjs", + "file_punycode_host_src.sjs", + "file_punycode_host_src.js", + "file_iframe_srcdoc.sjs", + "file_iframe_sandbox_srcdoc.html", + "file_iframe_sandbox_srcdoc.html^headers^", + "file_websocket_self.html", + "file_websocket_csp_upgrade.html", + "file_websocket_explicit.html", + "file_websocket_self_wsh.py", + "file_win_open_blocked.html", + "file_image_nonce.html", + "file_image_nonce.html^headers^", + "file_ignore_xfo.html", + "file_ignore_xfo.html^headers^", + "file_ro_ignore_xfo.html", + "file_ro_ignore_xfo.html^headers^", + "file_no_log_ignore_xfo.html", + "file_no_log_ignore_xfo.html^headers^", + "file_data_csp_inheritance.html", + "file_data_csp_merge.html", + "file_data_doc_ignore_meta_csp.html", + "file_report_font_cache-1.html", + "file_report_font_cache-2.html", + "file_report_font_cache-2.html^headers^", + "Ahem.ttf", + "file_independent_iframe_csp.html", + "file_upgrade_insecure_report_only.html", + "file_upgrade_insecure_report_only_server.sjs", +] +prefs = [ + "security.mixed_content.upgrade_display_content=false", + "javascript.options.experimental.shadow_realms=true", +] + +["test_301_redirect.html"] +skip-if = [ + "http3", + "http2", +] + +["test_302_redirect.html"] +skip-if = [ + "http3", + "http2", +] + +["test_303_redirect.html"] +skip-if = [ + "http3", + "http2", +] + +["test_307_redirect.html"] +skip-if = [ + "http3", + "http2", +] + +["test_CSP.html"] +skip-if = [ + "http3", + "http2", +] + +["test_allow_https_schemes.html"] + +["test_base-uri.html"] +skip-if = [ + "http3", + "http2", +] + +["test_blob_data_schemes.html"] + +["test_blob_uri_blocks_modals.html"] +skip-if = [ + "xorigin", + "os == 'linux'", + "asan", # alert should be blocked by CSP - got false, expected true + "tsan", # alert should be blocked by CSP - got false, expected true + "http3", + "http2", +] + +["test_block_all_mixed_content.html"] +tags = "mcb" + +["test_block_all_mixed_content_frame_navigation.html"] +tags = "mcb" +skip-if = [ + "http3", + "http2", +] + +["test_blocked_uri_in_reports.html"] +skip-if = [ + "http3", + "http2", +] + +["test_blocked_uri_in_violation_event_after_redirects.html"] +support-files = [ + "file_blocked_uri_in_violation_event_after_redirects.html", + "file_blocked_uri_in_violation_event_after_redirects.sjs", +] +skip-if = [ + "http3", + "http2", +] + +["test_blocked_uri_redirect_frame_src.html"] +support-files = [ + "file_blocked_uri_redirect_frame_src.html", + "file_blocked_uri_redirect_frame_src.html^headers^", + "file_blocked_uri_redirect_frame_src_server.sjs", +] +skip-if = [ + "http3", + "http2", +] + +["test_bug663567.html"] +skip-if = ["fission && xorigin && debug && os == 'win'"] # Bug 1716406 - New fission platform triage + +["test_bug802872.html"] +skip-if = [ + "http3", + "http2", +] + +["test_bug836922_npolicies.html"] +skip-if = [ + "verify", + "http3", + "http2", +] + +["test_bug885433.html"] + +["test_bug886164.html"] + +["test_bug888172.html"] + +["test_bug909029.html"] + +["test_bug910139.html"] +skip-if = ["verify"] + +["test_bug941404.html"] + +["test_bug1229639.html"] +skip-if = [ + "http3", + "http2", +] + +["test_bug1242019.html"] +skip-if = [ + "http3", + "http2", +] + +["test_bug1312272.html"] + +["test_bug1452037.html"] + +["test_bug1505412.html"] +skip-if = ["!debug"] + +["test_bug1579094.html"] + +["test_bug1738418.html"] +support-files = [ + "file_bug1738418_parent.html", + "file_bug1738418_parent.html^headers^", + "file_bug1738418_child.html", +] + +["test_bug1764343.html"] +support-files = [ + "file_bug1764343.html", +] + +["test_bug1777572.html"] +support-files = ["file_bug1777572.html"] +skip-if = ["os == 'android'"] # This unusual window.close/open test times out on Android. + +["test_child-src_iframe.html"] +skip-if = [ + "http3", + "http2", +] + +["test_child-src_worker-redirect.html"] +skip-if = [ + "http3", + "http2", +] + +["test_child-src_worker.html"] +skip-if = [ + "http3", + "http2", +] + +["test_child-src_worker_data.html"] +skip-if = [ + "http3", + "http2", +] + +["test_connect-src.html"] + +["test_csp_frame_ancestors_about_blank.html"] +support-files = [ + "file_csp_frame_ancestors_about_blank.html", + "file_csp_frame_ancestors_about_blank.html^headers^", +] + +["test_csp_style_src_empty_hash.html"] + +["test_csp_worker_inheritance.html"] +support-files = [ + "worker.sjs", + "worker_helper.js", + "main_csp_worker.html", + "main_csp_worker.html^headers^", +] +skip-if = [ + "http3", + "http2", +] + +["test_data_csp_inheritance.html"] + +["test_data_csp_merge.html"] + +["test_data_doc_ignore_meta_csp.html"] + +["test_docwrite_meta.html"] + +["test_dual_header.html"] + +["test_empty_directive.html"] + +["test_evalscript.html"] + +["test_evalscript_allowed_by_strict_dynamic.html"] + +["test_evalscript_blocked_by_strict_dynamic.html"] + +["test_fontloader.html"] + +["test_form-action.html"] + +["test_form_action_blocks_url.html"] + +["test_frame_ancestors_ro.html"] +skip-if = [ + "http3", + "http2", +] + +["test_frame_src.html"] +support-files = [ + "file_frame_src_frame_governs.html", + "file_frame_src_child_governs.html", + "file_frame_src.js", + "file_frame_src_inner.html", +] +skip-if = [ + "http3", + "http2", +] + +["test_frameancestors.html"] +skip-if = [ + "xorigin", # JavaScript error: http://mochi.xorigin-test:8888/tests/SimpleTest/TestRunner.js, line 157: SecurityError: Permission denied to access property "wrappedJSObject" on cross-origin object + "http3", + "http2", +] + +["test_frameancestors_userpass.html"] +skip-if = [ + "http3", + "http2", +] + +["test_hash_source.html"] +skip-if = ["fission && xorigin && debug"] # Bug 1716406 - New fission platform triage + +["test_iframe_sandbox.html"] +skip-if = [ + "fission && xorigin && debug && (os == 'win' || os == 'linux')", # Bug 1716406 - New fission platform triage + "http3", + "http2", +] + +["test_iframe_sandbox_srcdoc.html"] +skip-if = ["fission && xorigin && debug && os == 'win'"] # Bug 1716406 - New fission platform triage + +["test_iframe_sandbox_top_1.html"] + +["test_iframe_srcdoc.html"] + +["test_ignore_unsafe_inline.html"] +skip-if = ["xorigin"] # JavaScript error: http://mochi.xorigin-test:8888/tests/SimpleTest/TestRunner.js, line 157: SecurityError: Permission denied to access property "wrappedJSObject" on cross-origin object, [Child 3789, Main Thread] WARNING: NS_ENSURE_TRUE(request) failed: file /builds/worker/checkouts/gecko/netwerk/base/nsLoadGroup.cpp, line 591 + +["test_ignore_xfo.html"] +skip-if = [ + "xorigin", # JavaScript error: http://mochi.xorigin-test:8888/tests/SimpleTest/TestRunner.js, line 157: SecurityError: Permission denied to access property "wrappedJSObject" on cross-origin object + "http3", + "http2", +] + +["test_image_document.html"] +support-files = [ + "file_image_document_pixel.png", + "file_image_document_pixel.png^headers^", +] + +["test_image_nonce.html"] + +["test_independent_iframe_csp.html"] + +["test_inlinescript.html"] + +["test_inlinestyle.html"] + +["test_invalid_source_expression.html"] + +["test_leading_wildcard.html"] +skip-if = [ + "http3", + "http2", +] + +["test_link_rel_preload.html"] +support-files = ["file_link_rel_preload.html"] + +["test_meta_csp_self.html"] + +["test_meta_element.html"] + +["test_meta_header_dual.html"] + +["test_meta_whitespace_skipping.html"] + +["test_multi_policy_injection_bypass.html"] + +["test_multipartchannel.html"] +skip-if = [ + "http3", + "http2", +] + +["test_nonce_redirects.html"] + +["test_nonce_snapshot.html"] +support-files = ["file_nonce_snapshot.sjs"] + +["test_nonce_source.html"] +skip-if = [ + "http3", + "http2", +] + +["test_null_baseuri.html"] +skip-if = [ + "http3", + "http2", +] + +["test_object_inherit.html"] +support-files = ["file_object_inherit.html"] + +["test_parent_location_js.html"] +support-files = [ + "file_parent_location_js.html", + "file_iframe_parent_location_js.html", +] + +["test_path_matching.html"] +skip-if = [ + "http3", + "http2", +] + +["test_path_matching_redirect.html"] +skip-if = [ + "http3", + "http2", +] + +["test_ping.html"] +skip-if = [ + "http3", + "http2", +] + +["test_policyuri_regression_from_multipolicy.html"] + +["test_punycode_host_src.html"] +skip-if = [ + "http3", + "http2", +] + +["test_redirects.html"] +skip-if = [ + "http3", + "http2", +] + +["test_report.html"] +fail-if = ["xorigin"] +skip-if = [ + "http3", + "http2", +] + +["test_report_font_cache.html"] +skip-if = [ + "http3", + "http2", +] + +["test_report_for_import.html"] +fail-if = ["xorigin"] +skip-if = [ + "http3", + "http2", +] + +["test_report_uri_missing_in_report_only_header.html"] + +["test_sandbox.html"] +skip-if = ["true"] # Bug 1657934 + +["test_sandbox_allow_scripts.html"] +support-files = [ + "file_sandbox_allow_scripts.html", + "file_sandbox_allow_scripts.html^headers^", +] + +["test_scheme_relative_sources.html"] +skip-if = [ + "http3", + "http2", +] + +["test_script_template.html"] +support-files = [ + "file_script_template.html", + "file_script_template.js", +] + +["test_security_policy_violation_event.html"] + +["test_self_none_as_hostname_confusion.html"] + +["test_sendbeacon.html"] + +["test_service_worker.html"] + +["test_strict_dynamic.html"] +skip-if = [ + "http3", + "http2", +] + +["test_strict_dynamic_default_src.html"] +skip-if = [ + "http3", + "http2", +] + +["test_strict_dynamic_parser_inserted.html"] +skip-if = [ + "http3", + "http2", +] + +["test_subframe_run_js_if_allowed.html"] + +["test_svg_inline_style.html"] +support-files = [ + "file_svg_inline_style_base.html", + "file_svg_inline_style_csp.html", + "file_svg_srcset_inline_style_base.html", + "file_svg_srcset_inline_style_csp.html", + "file_svg_inline_style_server.sjs", +] + +["test_uir_top_nav.html"] +support-files = [ + "file_uir_top_nav.html", + "file_uir_top_nav_dummy.html", +] +skip-if = [ + "http3", + "http2", +] + +["test_uir_windowwatcher.html"] +support-files = [ + "file_windowwatcher_frameA.html", + "file_windowwatcher_subframeB.html", + "file_windowwatcher_subframeC.html", + "file_windowwatcher_subframeD.html", + "file_windowwatcher_win_open.html", +] +skip-if = [ + "http3", + "http2", +] + +["test_upgrade_insecure.html"] +skip-if = [ + "os == 'linux' && bits == 64", # Bug 1620516 + "os == 'android'", # Bug 1777028 +] + +["test_upgrade_insecure_cors.html"] +skip-if = [ + "http3", + "http2", +] + +["test_upgrade_insecure_docwrite_iframe.html"] + +["test_upgrade_insecure_loopback.html"] + +["test_upgrade_insecure_navigation.html"] +skip-if = [ + "http3", + "http2", +] + +["test_upgrade_insecure_navigation_redirect.html"] +support-files = [ + "file_upgrade_insecure_navigation_redirect.sjs", + "file_upgrade_insecure_navigation_redirect_same_origin.html", + "file_upgrade_insecure_navigation_redirect_cross_origin.html", +] +skip-if = [ + "http3", + "http2", +] + +["test_upgrade_insecure_report_only.html"] +skip-if = [ + "http3", + "http2", +] + +["test_upgrade_insecure_reporting.html"] +skip-if = [ + "http3", + "http2", +] + +["test_websocket_localhost.html"] +skip-if = [ + "os == 'android'", # no websocket support Bug 982828 + "http3", + "http2", +] + +["test_websocket_self.html"] +skip-if = [ + "os == 'android'", # no websocket support Bug 982828 + "http3", + "http2", +] + +["test_win_open_blocked.html"] + +["test_worker_src.html"] +support-files = [ + "file_worker_src_worker_governs.html", + "file_worker_src_child_governs.html", + "file_worker_src_script_governs.html", + "file_worker_src.js", + "file_spawn_worker.js", + "file_spawn_shared_worker.js", + "file_spawn_service_worker.js", +] +skip-if = [ + "http3", + "http2", +] + +["test_xslt_inherits_csp.html"] +support-files = [ + "file_xslt_inherits_csp.xml", + "file_xslt_inherits_csp.xml^headers^", + "file_xslt_inherits_csp.xsl", +] diff --git a/dom/security/test/csp/referrerdirective.sjs b/dom/security/test/csp/referrerdirective.sjs new file mode 100644 index 0000000000..267eaaede2 --- /dev/null +++ b/dom/security/test/csp/referrerdirective.sjs @@ -0,0 +1,40 @@ +// Used for bug 965727 to serve up really simple scripts reflecting the +// referrer sent to load this back to the loader. + +function handleRequest(request, response) { + // skip speculative loads. + + var splits = request.queryString.split("&"); + var params = {}; + splits.forEach(function (v) { + let parts = v.split("="); + params[parts[0]] = unescape(parts[1]); + }); + + var loadType = params.type; + var referrerLevel = "error"; + + if (request.hasHeader("Referer")) { + var referrer = request.getHeader("Referer"); + if (referrer.indexOf("file_testserver.sjs") > -1) { + referrerLevel = "full"; + } else { + referrerLevel = "origin"; + } + } else { + referrerLevel = "none"; + } + + var theScript = + 'window.postResult("' + loadType + '", "' + referrerLevel + '");'; + response.setHeader( + "Content-Type", + "application/javascript; charset=utf-8", + false + ); + response.setHeader("Cache-Control", "no-cache", false); + + if (request.method != "OPTIONS") { + response.write(theScript); + } +} diff --git a/dom/security/test/csp/test_301_redirect.html b/dom/security/test/csp/test_301_redirect.html new file mode 100644 index 0000000000..0aaed5bcf2 --- /dev/null +++ b/dom/security/test/csp/test_301_redirect.html @@ -0,0 +1,74 @@ + + + + + Test for Bug 650386 + + + + +Mozilla Bug 650386 +

+ +
+
+
+ + diff --git a/dom/security/test/csp/test_302_redirect.html b/dom/security/test/csp/test_302_redirect.html new file mode 100644 index 0000000000..330c1a64e9 --- /dev/null +++ b/dom/security/test/csp/test_302_redirect.html @@ -0,0 +1,74 @@ + + + + + Test for Bug 650386 + + + + +Mozilla Bug 650386 +

+ +
+
+
+ + diff --git a/dom/security/test/csp/test_303_redirect.html b/dom/security/test/csp/test_303_redirect.html new file mode 100644 index 0000000000..ecff523967 --- /dev/null +++ b/dom/security/test/csp/test_303_redirect.html @@ -0,0 +1,74 @@ + + + + + Test for Bug 650386 + + + + +Mozilla Bug 650386 +

+ +
+
+
+ + diff --git a/dom/security/test/csp/test_307_redirect.html b/dom/security/test/csp/test_307_redirect.html new file mode 100644 index 0000000000..40ebd592b3 --- /dev/null +++ b/dom/security/test/csp/test_307_redirect.html @@ -0,0 +1,75 @@ + + + + + Test for Bug 650386 + + + + +Mozilla Bug 650386 +

+ +
+
+
+ + diff --git a/dom/security/test/csp/test_CSP.html b/dom/security/test/csp/test_CSP.html new file mode 100644 index 0000000000..babb9db9bc --- /dev/null +++ b/dom/security/test/csp/test_CSP.html @@ -0,0 +1,130 @@ + + + + Test for Content Security Policy Connections + + + + +

+ + + + + + diff --git a/dom/security/test/csp/test_allow_https_schemes.html b/dom/security/test/csp/test_allow_https_schemes.html new file mode 100644 index 0000000000..be1f030fb9 --- /dev/null +++ b/dom/security/test/csp/test_allow_https_schemes.html @@ -0,0 +1,76 @@ + + + + Bug 826805 - Allow http and https for scheme-less sources + + + + + +

+ + + + + diff --git a/dom/security/test/csp/test_base-uri.html b/dom/security/test/csp/test_base-uri.html new file mode 100644 index 0000000000..4d5c5504af --- /dev/null +++ b/dom/security/test/csp/test_base-uri.html @@ -0,0 +1,124 @@ + + + + Bug 1045897 - Test CSP base-uri directive + + + + + +

+ + + + + diff --git a/dom/security/test/csp/test_blob_data_schemes.html b/dom/security/test/csp/test_blob_data_schemes.html new file mode 100644 index 0000000000..37a22db050 --- /dev/null +++ b/dom/security/test/csp/test_blob_data_schemes.html @@ -0,0 +1,89 @@ + + + + Bug 1086999 - Wildcard should not match blob:, data: + + + + + + + + + + diff --git a/dom/security/test/csp/test_blob_uri_blocks_modals.html b/dom/security/test/csp/test_blob_uri_blocks_modals.html new file mode 100644 index 0000000000..8d593ea256 --- /dev/null +++ b/dom/security/test/csp/test_blob_uri_blocks_modals.html @@ -0,0 +1,75 @@ + + + + + Bug 1432170 - Block alert box and new window open as per the sandbox + allow-scripts CSP + + + + + + + + diff --git a/dom/security/test/csp/test_block_all_mixed_content.html b/dom/security/test/csp/test_block_all_mixed_content.html new file mode 100644 index 0000000000..d60f904b6c --- /dev/null +++ b/dom/security/test/csp/test_block_all_mixed_content.html @@ -0,0 +1,99 @@ + + + + + Bug 1122236 - CSP: Implement block-all-mixed-content + + + + + + + + + + diff --git a/dom/security/test/csp/test_block_all_mixed_content_frame_navigation.html b/dom/security/test/csp/test_block_all_mixed_content_frame_navigation.html new file mode 100644 index 0000000000..b32c1fccd5 --- /dev/null +++ b/dom/security/test/csp/test_block_all_mixed_content_frame_navigation.html @@ -0,0 +1,46 @@ + + + + + Bug 1122236 - CSP: Implement block-all-mixed-content + + + + + + + + + + diff --git a/dom/security/test/csp/test_blocked_uri_in_reports.html b/dom/security/test/csp/test_blocked_uri_in_reports.html new file mode 100644 index 0000000000..f40d98efc5 --- /dev/null +++ b/dom/security/test/csp/test_blocked_uri_in_reports.html @@ -0,0 +1,80 @@ + + + + Bug 1069762 - Check blocked-uri in csp-reports after redirect + + + + + + + + + + diff --git a/dom/security/test/csp/test_blocked_uri_in_violation_event_after_redirects.html b/dom/security/test/csp/test_blocked_uri_in_violation_event_after_redirects.html new file mode 100644 index 0000000000..6965cbeb92 --- /dev/null +++ b/dom/security/test/csp/test_blocked_uri_in_violation_event_after_redirects.html @@ -0,0 +1,56 @@ + + + + Bug 1542194 - Check blockedURI in violation reports after redirects + + + + + + + + + + diff --git a/dom/security/test/csp/test_blocked_uri_redirect_frame_src.html b/dom/security/test/csp/test_blocked_uri_redirect_frame_src.html new file mode 100644 index 0000000000..a946718bc2 --- /dev/null +++ b/dom/security/test/csp/test_blocked_uri_redirect_frame_src.html @@ -0,0 +1,60 @@ + + + + Bug 1687342 - Check blocked-uri in csp-reports after frame redirect + + + + + + + + + + diff --git a/dom/security/test/csp/test_bug1229639.html b/dom/security/test/csp/test_bug1229639.html new file mode 100644 index 0000000000..e224fe1ffb --- /dev/null +++ b/dom/security/test/csp/test_bug1229639.html @@ -0,0 +1,51 @@ + + + + + Bug 1229639 - Percent encoded CSP path matching. + + + + +

+ + + + + + + diff --git a/dom/security/test/csp/test_bug1242019.html b/dom/security/test/csp/test_bug1242019.html new file mode 100644 index 0000000000..14e8f74baa --- /dev/null +++ b/dom/security/test/csp/test_bug1242019.html @@ -0,0 +1,51 @@ + + + + + + Test for Bug 1242019 + + + + +Mozilla Bug 1242019 +

+ + + +
+
+
+
+ + diff --git a/dom/security/test/csp/test_bug1312272.html b/dom/security/test/csp/test_bug1312272.html new file mode 100644 index 0000000000..b06b08d092 --- /dev/null +++ b/dom/security/test/csp/test_bug1312272.html @@ -0,0 +1,32 @@ + + + + + + Test for bug 1312272 + + + + + + + + + + diff --git a/dom/security/test/csp/test_bug1388015.html b/dom/security/test/csp/test_bug1388015.html new file mode 100644 index 0000000000..5ca0605688 --- /dev/null +++ b/dom/security/test/csp/test_bug1388015.html @@ -0,0 +1,46 @@ + + + + + Bug 1388015 - Test if Firefox respect Port in Wildcard Host + + + + + + + + Should be Blocked + + + diff --git a/dom/security/test/csp/test_bug1452037.html b/dom/security/test/csp/test_bug1452037.html new file mode 100644 index 0000000000..fa46e91291 --- /dev/null +++ b/dom/security/test/csp/test_bug1452037.html @@ -0,0 +1,41 @@ + + + + Test if "script-src: sha-... " Allowlists "javascript:" URIs + + + + + + + + + + diff --git a/dom/security/test/csp/test_bug1505412.html b/dom/security/test/csp/test_bug1505412.html new file mode 100644 index 0000000000..717af2054b --- /dev/null +++ b/dom/security/test/csp/test_bug1505412.html @@ -0,0 +1,50 @@ + + + + + Bug 1505412 CSP-RO reports violations in inline-scripts with nonce + + + + + +

+ + + Test for 1505412 + + + + + \ No newline at end of file diff --git a/dom/security/test/csp/test_bug1579094.html b/dom/security/test/csp/test_bug1579094.html new file mode 100644 index 0000000000..b3568586d4 --- /dev/null +++ b/dom/security/test/csp/test_bug1579094.html @@ -0,0 +1,31 @@ + + + + Test if Wildcard CSP supports ExternalProtocol + + + + + + +

+ + + + + + + diff --git a/dom/security/test/csp/test_bug1764343.html b/dom/security/test/csp/test_bug1764343.html new file mode 100644 index 0000000000..1af9a710fe --- /dev/null +++ b/dom/security/test/csp/test_bug1764343.html @@ -0,0 +1,116 @@ + + + + + Bug 1764343 - CSP inheritance for same-origin iframes + + + + + + + + + + + + diff --git a/dom/security/test/csp/test_bug1777572.html b/dom/security/test/csp/test_bug1777572.html new file mode 100644 index 0000000000..f735f4fb6a --- /dev/null +++ b/dom/security/test/csp/test_bug1777572.html @@ -0,0 +1,40 @@ + + + + + bug 1777572 + + + + + +

+ +

+
+
diff --git a/dom/security/test/csp/test_bug663567.html b/dom/security/test/csp/test_bug663567.html
new file mode 100644
index 0000000000..137d459654
--- /dev/null
+++ b/dom/security/test/csp/test_bug663567.html
@@ -0,0 +1,76 @@
+
+
+
+  Test if XSLT stylesheet is subject to document's CSP
+  
+  
+  
+
+
+  

+ + + + + + + diff --git a/dom/security/test/csp/test_bug802872.html b/dom/security/test/csp/test_bug802872.html new file mode 100644 index 0000000000..956159ddcc --- /dev/null +++ b/dom/security/test/csp/test_bug802872.html @@ -0,0 +1,53 @@ + + + + Bug 802872 + + + + + +

+ + + + + + diff --git a/dom/security/test/csp/test_bug836922_npolicies.html b/dom/security/test/csp/test_bug836922_npolicies.html new file mode 100644 index 0000000000..e418969e3d --- /dev/null +++ b/dom/security/test/csp/test_bug836922_npolicies.html @@ -0,0 +1,235 @@ + + + + Test for Content Security Policy multiple policy support (regular and Report-Only mode) + + + + +

+ + + + + + + diff --git a/dom/security/test/csp/test_bug885433.html b/dom/security/test/csp/test_bug885433.html new file mode 100644 index 0000000000..c7c17d25b6 --- /dev/null +++ b/dom/security/test/csp/test_bug885433.html @@ -0,0 +1,61 @@ + + + + Test for Content Security Policy inline stylesheets stuff + + + + +

+ + + + + + + + diff --git a/dom/security/test/csp/test_bug886164.html b/dom/security/test/csp/test_bug886164.html new file mode 100644 index 0000000000..5347d42ed8 --- /dev/null +++ b/dom/security/test/csp/test_bug886164.html @@ -0,0 +1,172 @@ + + + + + Bug 886164 - Enforce CSP in sandboxed iframe + + + + +

+ + + + + + + + + + + diff --git a/dom/security/test/csp/test_bug888172.html b/dom/security/test/csp/test_bug888172.html new file mode 100644 index 0000000000..a78258e21f --- /dev/null +++ b/dom/security/test/csp/test_bug888172.html @@ -0,0 +1,73 @@ + + + + Bug 888172 - CSP 1.0 does not process 'unsafe-inline' or 'unsafe-eval' for default-src + + + + +

+ + + + + + + + + diff --git a/dom/security/test/csp/test_bug909029.html b/dom/security/test/csp/test_bug909029.html new file mode 100644 index 0000000000..7a3ac81a1b --- /dev/null +++ b/dom/security/test/csp/test_bug909029.html @@ -0,0 +1,129 @@ + + + + Bug 909029 - CSP source-lists ignore some source expressions like 'unsafe-inline' when * or 'none' are used (e.g., style-src, script-src) + + + + + + + + diff --git a/dom/security/test/csp/test_bug910139.html b/dom/security/test/csp/test_bug910139.html new file mode 100644 index 0000000000..bbebedf877 --- /dev/null +++ b/dom/security/test/csp/test_bug910139.html @@ -0,0 +1,66 @@ + + + + CSP should block XSLT as script, not as style + + + + + +

+ + + + + + + diff --git a/dom/security/test/csp/test_bug941404.html b/dom/security/test/csp/test_bug941404.html new file mode 100644 index 0000000000..7c35c38aa1 --- /dev/null +++ b/dom/security/test/csp/test_bug941404.html @@ -0,0 +1,107 @@ + + + + + Bug 941404 - Data documents should not set CSP + + + + +

+ + + + + + + diff --git a/dom/security/test/csp/test_child-src_iframe.html b/dom/security/test/csp/test_child-src_iframe.html new file mode 100644 index 0000000000..2b85e280bd --- /dev/null +++ b/dom/security/test/csp/test_child-src_iframe.html @@ -0,0 +1,113 @@ + + + + Bug 1045891 + + + + + +

+ + + + + diff --git a/dom/security/test/csp/test_child-src_worker-redirect.html b/dom/security/test/csp/test_child-src_worker-redirect.html new file mode 100644 index 0000000000..a1b1c9c2b4 --- /dev/null +++ b/dom/security/test/csp/test_child-src_worker-redirect.html @@ -0,0 +1,125 @@ + + + + Bug 1045891 + + + + + +

+ + + + + diff --git a/dom/security/test/csp/test_child-src_worker.html b/dom/security/test/csp/test_child-src_worker.html new file mode 100644 index 0000000000..205b67f098 --- /dev/null +++ b/dom/security/test/csp/test_child-src_worker.html @@ -0,0 +1,147 @@ + + + + Bug 1045891 + + + + + +

+ + + + + diff --git a/dom/security/test/csp/test_child-src_worker_data.html b/dom/security/test/csp/test_child-src_worker_data.html new file mode 100644 index 0000000000..9d36e73e0c --- /dev/null +++ b/dom/security/test/csp/test_child-src_worker_data.html @@ -0,0 +1,126 @@ + + + + Bug 1045891 + + + + + +

+ + + + + diff --git a/dom/security/test/csp/test_connect-src.html b/dom/security/test/csp/test_connect-src.html new file mode 100644 index 0000000000..1ae4482dd8 --- /dev/null +++ b/dom/security/test/csp/test_connect-src.html @@ -0,0 +1,129 @@ + + + + Bug 1031530 and Bug 1139667 - Test mapping of XMLHttpRequest and fetch() to connect-src + + + + + +

+ + + + + diff --git a/dom/security/test/csp/test_csp_frame_ancestors_about_blank.html b/dom/security/test/csp/test_csp_frame_ancestors_about_blank.html new file mode 100644 index 0000000000..8f57d9e133 --- /dev/null +++ b/dom/security/test/csp/test_csp_frame_ancestors_about_blank.html @@ -0,0 +1,59 @@ + + + + + Bug 1668071 - CSP frame-ancestors in about:blank + + + + + + + + diff --git a/dom/security/test/csp/test_csp_style_src_empty_hash.html b/dom/security/test/csp/test_csp_style_src_empty_hash.html new file mode 100644 index 0000000000..b500c196e6 --- /dev/null +++ b/dom/security/test/csp/test_csp_style_src_empty_hash.html @@ -0,0 +1,32 @@ + + + + Bug 1609122 - Empty Style Element with valid style-src hash + + + + + + + + + + + diff --git a/dom/security/test/csp/test_csp_worker_inheritance.html b/dom/security/test/csp/test_csp_worker_inheritance.html new file mode 100644 index 0000000000..ebf6bea8a6 --- /dev/null +++ b/dom/security/test/csp/test_csp_worker_inheritance.html @@ -0,0 +1,20 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + + + + Test for Bug 1475849 + + +

+ + + + + + diff --git a/dom/security/test/csp/test_data_csp_inheritance.html b/dom/security/test/csp/test_data_csp_inheritance.html new file mode 100644 index 0000000000..dd7f3174a2 --- /dev/null +++ b/dom/security/test/csp/test_data_csp_inheritance.html @@ -0,0 +1,36 @@ + + + + Bug 1381761 - Treating 'data:' documents as unique, opaque origins should still inherit the CSP + + + + + + + + + + diff --git a/dom/security/test/csp/test_data_csp_merge.html b/dom/security/test/csp/test_data_csp_merge.html new file mode 100644 index 0000000000..87219c406d --- /dev/null +++ b/dom/security/test/csp/test_data_csp_merge.html @@ -0,0 +1,36 @@ + + + + Bug 1386183 - Meta CSP on data: URI iframe should be merged with toplevel CSP + + + + + + + + + + diff --git a/dom/security/test/csp/test_data_doc_ignore_meta_csp.html b/dom/security/test/csp/test_data_doc_ignore_meta_csp.html new file mode 100644 index 0000000000..6f0a3fbbf6 --- /dev/null +++ b/dom/security/test/csp/test_data_doc_ignore_meta_csp.html @@ -0,0 +1,39 @@ + + + + Bug 1382869: data document should ignore meta csp + + + + + + + + + diff --git a/dom/security/test/csp/test_docwrite_meta.html b/dom/security/test/csp/test_docwrite_meta.html new file mode 100644 index 0000000000..776f1bb32f --- /dev/null +++ b/dom/security/test/csp/test_docwrite_meta.html @@ -0,0 +1,86 @@ + + + + + Bug 663570 - Implement Content Security Policy via meta tag + + + + + +

+ + + + + + + diff --git a/dom/security/test/csp/test_dual_header.html b/dom/security/test/csp/test_dual_header.html new file mode 100644 index 0000000000..cfea86103b --- /dev/null +++ b/dom/security/test/csp/test_dual_header.html @@ -0,0 +1,66 @@ + + + + Bug 1036399 - Multiple CSP policies should be combined towards an intersection + + + + + +

+ + + + + diff --git a/dom/security/test/csp/test_empty_directive.html b/dom/security/test/csp/test_empty_directive.html new file mode 100644 index 0000000000..81c5df8403 --- /dev/null +++ b/dom/security/test/csp/test_empty_directive.html @@ -0,0 +1,51 @@ + + + + + + Test for Bug 1439425 + + + + +Mozilla Bug 1439425 +

+ + + +
+
+
+
+ + diff --git a/dom/security/test/csp/test_evalscript.html b/dom/security/test/csp/test_evalscript.html new file mode 100644 index 0000000000..bf1621f81e --- /dev/null +++ b/dom/security/test/csp/test_evalscript.html @@ -0,0 +1,59 @@ + + + + Test for Content Security Policy "no eval" base restriction + + + + +

+ + + + + + + diff --git a/dom/security/test/csp/test_evalscript_allowed_by_strict_dynamic.html b/dom/security/test/csp/test_evalscript_allowed_by_strict_dynamic.html new file mode 100644 index 0000000000..9b06bdaf82 --- /dev/null +++ b/dom/security/test/csp/test_evalscript_allowed_by_strict_dynamic.html @@ -0,0 +1,37 @@ + + + + + + Bug 1439330 - CSP: eval is not blocked if 'strict-dynamic' is enabled + + + + + + + + diff --git a/dom/security/test/csp/test_evalscript_blocked_by_strict_dynamic.html b/dom/security/test/csp/test_evalscript_blocked_by_strict_dynamic.html new file mode 100644 index 0000000000..ee94f250d7 --- /dev/null +++ b/dom/security/test/csp/test_evalscript_blocked_by_strict_dynamic.html @@ -0,0 +1,37 @@ + + + + + + Bug 1439330 - CSP: eval is not blocked if 'strict-dynamic' is enabled + + + + + + + + diff --git a/dom/security/test/csp/test_fontloader.html b/dom/security/test/csp/test_fontloader.html new file mode 100644 index 0000000000..2f68223af1 --- /dev/null +++ b/dom/security/test/csp/test_fontloader.html @@ -0,0 +1,98 @@ + + + + + Bug 1122236 - CSP: Implement block-all-mixed-content + + + + + + + + + + + + + diff --git a/dom/security/test/csp/test_form-action.html b/dom/security/test/csp/test_form-action.html new file mode 100644 index 0000000000..7bbc52a116 --- /dev/null +++ b/dom/security/test/csp/test_form-action.html @@ -0,0 +1,105 @@ + + + + Bug 529697 - Test mapping of form submission to form-action + + + + + +

+ + + + + diff --git a/dom/security/test/csp/test_form_action_blocks_url.html b/dom/security/test/csp/test_form_action_blocks_url.html new file mode 100644 index 0000000000..f835504ff4 --- /dev/null +++ b/dom/security/test/csp/test_form_action_blocks_url.html @@ -0,0 +1,76 @@ + + + + Bug 1251043 - Test form-action blocks URL + + + + + + + + + + diff --git a/dom/security/test/csp/test_frame_ancestors_ro.html b/dom/security/test/csp/test_frame_ancestors_ro.html new file mode 100644 index 0000000000..1cfe6be1cd --- /dev/null +++ b/dom/security/test/csp/test_frame_ancestors_ro.html @@ -0,0 +1,69 @@ + + + + Test for frame-ancestors support in Content-Security-Policy-Report-Only + + + + + + + + diff --git a/dom/security/test/csp/test_frame_src.html b/dom/security/test/csp/test_frame_src.html new file mode 100644 index 0000000000..f87549b72b --- /dev/null +++ b/dom/security/test/csp/test_frame_src.html @@ -0,0 +1,84 @@ + + + + + Bug 1302667 - Test frame-src + + + + + + + + + diff --git a/dom/security/test/csp/test_frameancestors.html b/dom/security/test/csp/test_frameancestors.html new file mode 100644 index 0000000000..8b44ba72fb --- /dev/null +++ b/dom/security/test/csp/test_frameancestors.html @@ -0,0 +1,160 @@ + + + + Test for Content Security Policy Frame Ancestors directive + + + + +

+ + + + + + diff --git a/dom/security/test/csp/test_frameancestors_userpass.html b/dom/security/test/csp/test_frameancestors_userpass.html new file mode 100644 index 0000000000..332318fe17 --- /dev/null +++ b/dom/security/test/csp/test_frameancestors_userpass.html @@ -0,0 +1,148 @@ + + + + Test for Userpass in Frame Ancestors directive + + + + +

+ + + + + + diff --git a/dom/security/test/csp/test_hash_source.html b/dom/security/test/csp/test_hash_source.html new file mode 100644 index 0000000000..2334ae0101 --- /dev/null +++ b/dom/security/test/csp/test_hash_source.html @@ -0,0 +1,135 @@ + + + + Test CSP 1.1 hash-source for inline scripts and styles + + + + + +

+ + + + + diff --git a/dom/security/test/csp/test_iframe_sandbox.html b/dom/security/test/csp/test_iframe_sandbox.html new file mode 100644 index 0000000000..cd7417bc8b --- /dev/null +++ b/dom/security/test/csp/test_iframe_sandbox.html @@ -0,0 +1,240 @@ + + + + + + Tests for Bug 671389 + + + + + + Mozilla Bug 671389 - Implement CSP sandbox directive +

+
+
+ + diff --git a/dom/security/test/csp/test_iframe_sandbox_srcdoc.html b/dom/security/test/csp/test_iframe_sandbox_srcdoc.html new file mode 100644 index 0000000000..9c36aa5447 --- /dev/null +++ b/dom/security/test/csp/test_iframe_sandbox_srcdoc.html @@ -0,0 +1,62 @@ + + + + + Bug 1073952 - CSP should restrict scripts in srcdoc iframe even if sandboxed + + + + +

Bug 1073952

+ + + + diff --git a/dom/security/test/csp/test_iframe_sandbox_top_1.html b/dom/security/test/csp/test_iframe_sandbox_top_1.html new file mode 100644 index 0000000000..c1ade7ac6c --- /dev/null +++ b/dom/security/test/csp/test_iframe_sandbox_top_1.html @@ -0,0 +1,80 @@ + + + + + + Tests for Bug 671389 + + + + + + +Mozilla Bug 671389 - Implement CSP sandbox directive +

+
+ I am a top-level page sandboxed with "allow-scripts allow-forms + allow-same-origin". +
+ + diff --git a/dom/security/test/csp/test_iframe_sandbox_top_1.html^headers^ b/dom/security/test/csp/test_iframe_sandbox_top_1.html^headers^ new file mode 100644 index 0000000000..d9cd0606e7 --- /dev/null +++ b/dom/security/test/csp/test_iframe_sandbox_top_1.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: sAnDbOx aLLow-FOrms aLlOw-ScRiPtS ALLOW-same-origin diff --git a/dom/security/test/csp/test_iframe_srcdoc.html b/dom/security/test/csp/test_iframe_srcdoc.html new file mode 100644 index 0000000000..04694aa5e0 --- /dev/null +++ b/dom/security/test/csp/test_iframe_srcdoc.html @@ -0,0 +1,140 @@ + + + + Bug 1073952 - Test CSP enforcement within iframe srcdoc + + + + + + + + + + diff --git a/dom/security/test/csp/test_ignore_unsafe_inline.html b/dom/security/test/csp/test_ignore_unsafe_inline.html new file mode 100644 index 0000000000..09d08157da --- /dev/null +++ b/dom/security/test/csp/test_ignore_unsafe_inline.html @@ -0,0 +1,122 @@ + + + + Bug 1004703 - ignore 'unsafe-inline' if nonce- or hash-source specified + + + + + + + + + + diff --git a/dom/security/test/csp/test_ignore_xfo.html b/dom/security/test/csp/test_ignore_xfo.html new file mode 100644 index 0000000000..5dbfecd18d --- /dev/null +++ b/dom/security/test/csp/test_ignore_xfo.html @@ -0,0 +1,120 @@ + + + + Bug 1024557: Ignore x-frame-options if CSP with frame-ancestors exists + + + + + + + + + + + + diff --git a/dom/security/test/csp/test_image_document.html b/dom/security/test/csp/test_image_document.html new file mode 100644 index 0000000000..eba83f95a7 --- /dev/null +++ b/dom/security/test/csp/test_image_document.html @@ -0,0 +1,35 @@ + + + + + Bug 1627235: Test CSP for images loaded as iframe + + + + + + + + + + diff --git a/dom/security/test/csp/test_image_nonce.html b/dom/security/test/csp/test_image_nonce.html new file mode 100644 index 0000000000..dd6bc13922 --- /dev/null +++ b/dom/security/test/csp/test_image_nonce.html @@ -0,0 +1,60 @@ + + + + + Bug 1139297 - Implement CSP upgrade-insecure-requests directive + + + + + + + + + + diff --git a/dom/security/test/csp/test_independent_iframe_csp.html b/dom/security/test/csp/test_independent_iframe_csp.html new file mode 100644 index 0000000000..9549263a11 --- /dev/null +++ b/dom/security/test/csp/test_independent_iframe_csp.html @@ -0,0 +1,79 @@ + + + + + Bug 1419222 - iFrame CSP should not affect parent document CSP + + + + + +

+ + + + + diff --git a/dom/security/test/csp/test_inlinescript.html b/dom/security/test/csp/test_inlinescript.html new file mode 100644 index 0000000000..99b055f0c7 --- /dev/null +++ b/dom/security/test/csp/test_inlinescript.html @@ -0,0 +1,123 @@ + + + + + Test for Content Security Policy Frame Ancestors directive + + + + + +

+ + + + + + + diff --git a/dom/security/test/csp/test_inlinestyle.html b/dom/security/test/csp/test_inlinestyle.html new file mode 100644 index 0000000000..dc15dc5078 --- /dev/null +++ b/dom/security/test/csp/test_inlinestyle.html @@ -0,0 +1,107 @@ + + + + Test for Content Security Policy inline stylesheets stuff + + + + +

+ + + + + + + + diff --git a/dom/security/test/csp/test_invalid_source_expression.html b/dom/security/test/csp/test_invalid_source_expression.html new file mode 100644 index 0000000000..c170dc2a27 --- /dev/null +++ b/dom/security/test/csp/test_invalid_source_expression.html @@ -0,0 +1,57 @@ + + + + Bug 1086612 - CSP: Let source expression be the empty set in case no valid source can be parsed + + + + + +

+ + + + + diff --git a/dom/security/test/csp/test_leading_wildcard.html b/dom/security/test/csp/test_leading_wildcard.html new file mode 100644 index 0000000000..53994b0013 --- /dev/null +++ b/dom/security/test/csp/test_leading_wildcard.html @@ -0,0 +1,101 @@ + + + + Bug 1032303 - CSP - Keep FULL STOP when matching *.foo.com to disallow loads from foo.com + + + + + +

+ + + + + diff --git a/dom/security/test/csp/test_link_rel_preload.html b/dom/security/test/csp/test_link_rel_preload.html new file mode 100644 index 0000000000..e2b226ff05 --- /dev/null +++ b/dom/security/test/csp/test_link_rel_preload.html @@ -0,0 +1,73 @@ + + + + Bug 1599791 - Test link rel=preload + + + + + + + + diff --git a/dom/security/test/csp/test_meta_csp_self.html b/dom/security/test/csp/test_meta_csp_self.html new file mode 100644 index 0000000000..8d7d5812a9 --- /dev/null +++ b/dom/security/test/csp/test_meta_csp_self.html @@ -0,0 +1,63 @@ + + + + Bug 1387871 - CSP: Test 'self' within meta csp in data: URI iframe + + + + + + + + + diff --git a/dom/security/test/csp/test_meta_element.html b/dom/security/test/csp/test_meta_element.html new file mode 100644 index 0000000000..42cddbacbf --- /dev/null +++ b/dom/security/test/csp/test_meta_element.html @@ -0,0 +1,91 @@ + + + + + Bug 663570 - Implement Content Security Policy via <meta> tag + + + + + +

+ + + + + diff --git a/dom/security/test/csp/test_meta_header_dual.html b/dom/security/test/csp/test_meta_header_dual.html new file mode 100644 index 0000000000..679512d068 --- /dev/null +++ b/dom/security/test/csp/test_meta_header_dual.html @@ -0,0 +1,135 @@ + + + + + Bug 663570 - Implement Content Security Policy via meta tag + + + + + +

+ + + + + diff --git a/dom/security/test/csp/test_meta_whitespace_skipping.html b/dom/security/test/csp/test_meta_whitespace_skipping.html new file mode 100644 index 0000000000..2f622c3a33 --- /dev/null +++ b/dom/security/test/csp/test_meta_whitespace_skipping.html @@ -0,0 +1,81 @@ + + + + + Bug 1261634 - Update whitespace skipping for meta csp + + + + + + + + + + diff --git a/dom/security/test/csp/test_multi_policy_injection_bypass.html b/dom/security/test/csp/test_multi_policy_injection_bypass.html new file mode 100644 index 0000000000..cbb981405b --- /dev/null +++ b/dom/security/test/csp/test_multi_policy_injection_bypass.html @@ -0,0 +1,119 @@ + + + + + Test for Bug 717511 + + + + +

+ + + + + + + + diff --git a/dom/security/test/csp/test_multipartchannel.html b/dom/security/test/csp/test_multipartchannel.html new file mode 100644 index 0000000000..2708611e6d --- /dev/null +++ b/dom/security/test/csp/test_multipartchannel.html @@ -0,0 +1,68 @@ + + + + + Bug 1416045/Bug 1223743 - CSP: Check baseChannel for CSP when loading multipart channel + + + + + + + + + + + diff --git a/dom/security/test/csp/test_nonce_redirects.html b/dom/security/test/csp/test_nonce_redirects.html new file mode 100644 index 0000000000..9b9e5e347d --- /dev/null +++ b/dom/security/test/csp/test_nonce_redirects.html @@ -0,0 +1,47 @@ + + + + + Bug 1469150:Scripts with valid nonce get blocked if URL redirects + + + + + + + + + + diff --git a/dom/security/test/csp/test_nonce_snapshot.html b/dom/security/test/csp/test_nonce_snapshot.html new file mode 100644 index 0000000000..6670d6868f --- /dev/null +++ b/dom/security/test/csp/test_nonce_snapshot.html @@ -0,0 +1,35 @@ + + + + + Bug 1509738 - Snapshot nonce at load start time + + + + + + + + + diff --git a/dom/security/test/csp/test_nonce_source.html b/dom/security/test/csp/test_nonce_source.html new file mode 100644 index 0000000000..e11452c6e1 --- /dev/null +++ b/dom/security/test/csp/test_nonce_source.html @@ -0,0 +1,122 @@ + + + + Test CSP 1.1 nonce-source for scripts and styles + + + + + +

+ + + + + diff --git a/dom/security/test/csp/test_null_baseuri.html b/dom/security/test/csp/test_null_baseuri.html new file mode 100644 index 0000000000..324b644f83 --- /dev/null +++ b/dom/security/test/csp/test_null_baseuri.html @@ -0,0 +1,67 @@ + + + + Bug 1121857 - document.baseURI should not get blocked if baseURI is null + + + + + +

+ + + + + diff --git a/dom/security/test/csp/test_object_inherit.html b/dom/security/test/csp/test_object_inherit.html new file mode 100644 index 0000000000..0d563bde3f --- /dev/null +++ b/dom/security/test/csp/test_object_inherit.html @@ -0,0 +1,30 @@ + + + + Bug 1457100: Test OBJECT inherits CSP if needed + + + + + + + + + diff --git a/dom/security/test/csp/test_parent_location_js.html b/dom/security/test/csp/test_parent_location_js.html new file mode 100644 index 0000000000..d456c809f2 --- /dev/null +++ b/dom/security/test/csp/test_parent_location_js.html @@ -0,0 +1,38 @@ + + + + Bug 1550414: Add CSP test for setting parent location to javascript: + + + + + + + + + diff --git a/dom/security/test/csp/test_path_matching.html b/dom/security/test/csp/test_path_matching.html new file mode 100644 index 0000000000..a54de0a25c --- /dev/null +++ b/dom/security/test/csp/test_path_matching.html @@ -0,0 +1,115 @@ + + + + Bug 808292 - Implement path-level host-source matching to CSP + + + + + +

+ + + + + diff --git a/dom/security/test/csp/test_path_matching_redirect.html b/dom/security/test/csp/test_path_matching_redirect.html new file mode 100644 index 0000000000..d3b2771d0a --- /dev/null +++ b/dom/security/test/csp/test_path_matching_redirect.html @@ -0,0 +1,89 @@ + + + + Bug 808292 - Implement path-level host-source matching to CSP (redirects) + + + + + +

+ + + + + diff --git a/dom/security/test/csp/test_ping.html b/dom/security/test/csp/test_ping.html new file mode 100644 index 0000000000..3f911b7b6a --- /dev/null +++ b/dom/security/test/csp/test_ping.html @@ -0,0 +1,103 @@ + + + + Bug 1100181 - CSP: Enforce connect-src when submitting pings + + + + + + + + + + diff --git a/dom/security/test/csp/test_policyuri_regression_from_multipolicy.html b/dom/security/test/csp/test_policyuri_regression_from_multipolicy.html new file mode 100644 index 0000000000..8838f2fc45 --- /dev/null +++ b/dom/security/test/csp/test_policyuri_regression_from_multipolicy.html @@ -0,0 +1,27 @@ + + + + Test for Bug 924708 + + + + + + + + + diff --git a/dom/security/test/csp/test_punycode_host_src.html b/dom/security/test/csp/test_punycode_host_src.html new file mode 100644 index 0000000000..3735275d34 --- /dev/null +++ b/dom/security/test/csp/test_punycode_host_src.html @@ -0,0 +1,81 @@ + + + + + Bug 1224225 - CSP source matching should work for punycoded domain names + + + + + + + + + + diff --git a/dom/security/test/csp/test_redirects.html b/dom/security/test/csp/test_redirects.html new file mode 100644 index 0000000000..3993560c14 --- /dev/null +++ b/dom/security/test/csp/test_redirects.html @@ -0,0 +1,142 @@ + + + + Tests for Content Security Policy during redirects + + + + +

+ + + +

+
+
+
+
+
diff --git a/dom/security/test/csp/test_report.html b/dom/security/test/csp/test_report.html
new file mode 100644
index 0000000000..fc10cd0341
--- /dev/null
+++ b/dom/security/test/csp/test_report.html
@@ -0,0 +1,113 @@
+
+
+
+
+  Test for Bug 548193
+  
+  
+
+
+

+ + + + + + + diff --git a/dom/security/test/csp/test_report_font_cache.html b/dom/security/test/csp/test_report_font_cache.html new file mode 100644 index 0000000000..40577a1e00 --- /dev/null +++ b/dom/security/test/csp/test_report_font_cache.html @@ -0,0 +1,56 @@ + + + + + + diff --git a/dom/security/test/csp/test_report_for_import.html b/dom/security/test/csp/test_report_for_import.html new file mode 100644 index 0000000000..ddeee3b507 --- /dev/null +++ b/dom/security/test/csp/test_report_for_import.html @@ -0,0 +1,109 @@ + + + + + Test for Bug 548193 + + + + +

+ + + + + + + diff --git a/dom/security/test/csp/test_report_uri_missing_in_report_only_header.html b/dom/security/test/csp/test_report_uri_missing_in_report_only_header.html new file mode 100644 index 0000000000..dc7eff2ac8 --- /dev/null +++ b/dom/security/test/csp/test_report_uri_missing_in_report_only_header.html @@ -0,0 +1,54 @@ + + + + + + Test for Bug 847081 + + + + +Mozilla Bug 847081 +

+ + + +
+
+
+ + diff --git a/dom/security/test/csp/test_sandbox.html b/dom/security/test/csp/test_sandbox.html new file mode 100644 index 0000000000..9fa123eadf --- /dev/null +++ b/dom/security/test/csp/test_sandbox.html @@ -0,0 +1,249 @@ + + + + + Tests for bugs 886164 and 671389 + + + + +

+
+
+ + + + diff --git a/dom/security/test/csp/test_sandbox_allow_scripts.html b/dom/security/test/csp/test_sandbox_allow_scripts.html new file mode 100644 index 0000000000..68544a5178 --- /dev/null +++ b/dom/security/test/csp/test_sandbox_allow_scripts.html @@ -0,0 +1,31 @@ + + + + Bug 1396320: Fix CSP sandbox regression for allow-scripts + + + + + + + + diff --git a/dom/security/test/csp/test_scheme_relative_sources.html b/dom/security/test/csp/test_scheme_relative_sources.html new file mode 100644 index 0000000000..3de3d98d69 --- /dev/null +++ b/dom/security/test/csp/test_scheme_relative_sources.html @@ -0,0 +1,91 @@ + + + + Bug 921493 - CSP: test allowlisting of scheme-relative sources + + + + + + + + + + diff --git a/dom/security/test/csp/test_script_template.html b/dom/security/test/csp/test_script_template.html new file mode 100644 index 0000000000..a71ebfe960 --- /dev/null +++ b/dom/security/test/csp/test_script_template.html @@ -0,0 +1,60 @@ + + + + Bug 1548385 - CSP: Test script template + + + + + + + + + diff --git a/dom/security/test/csp/test_security_policy_violation_event.html b/dom/security/test/csp/test_security_policy_violation_event.html new file mode 100644 index 0000000000..0d5cfade9c --- /dev/null +++ b/dom/security/test/csp/test_security_policy_violation_event.html @@ -0,0 +1,15 @@ + + + + + + diff --git a/dom/security/test/csp/test_self_none_as_hostname_confusion.html b/dom/security/test/csp/test_self_none_as_hostname_confusion.html new file mode 100644 index 0000000000..5f6958220e --- /dev/null +++ b/dom/security/test/csp/test_self_none_as_hostname_confusion.html @@ -0,0 +1,53 @@ + + + + + + Test for Bug 587377 + + + + +Mozilla Bug 587377 +

+ + + +
+
+
+
+ + diff --git a/dom/security/test/csp/test_sendbeacon.html b/dom/security/test/csp/test_sendbeacon.html new file mode 100644 index 0000000000..3b0df34c05 --- /dev/null +++ b/dom/security/test/csp/test_sendbeacon.html @@ -0,0 +1,34 @@ + + + + + Bug 1234813 - sendBeacon should not throw if blocked by Content Policy + + + + + +

+ + + + + diff --git a/dom/security/test/csp/test_service_worker.html b/dom/security/test/csp/test_service_worker.html new file mode 100644 index 0000000000..1c274990f8 --- /dev/null +++ b/dom/security/test/csp/test_service_worker.html @@ -0,0 +1,61 @@ + + + + Bug 1208559 - ServiceWorker registration not governed by CSP + + + + + + + + + + diff --git a/dom/security/test/csp/test_strict_dynamic.html b/dom/security/test/csp/test_strict_dynamic.html new file mode 100644 index 0000000000..f894e6d447 --- /dev/null +++ b/dom/security/test/csp/test_strict_dynamic.html @@ -0,0 +1,133 @@ + + + + Bug 1299483 - CSP: Implement 'strict-dynamic' + + + + + + + + + + diff --git a/dom/security/test/csp/test_strict_dynamic_default_src.html b/dom/security/test/csp/test_strict_dynamic_default_src.html new file mode 100644 index 0000000000..53eb899ab2 --- /dev/null +++ b/dom/security/test/csp/test_strict_dynamic_default_src.html @@ -0,0 +1,136 @@ + + + + Bug 1299483 - CSP: Implement 'strict-dynamic' + + + + + + + + + + diff --git a/dom/security/test/csp/test_strict_dynamic_parser_inserted.html b/dom/security/test/csp/test_strict_dynamic_parser_inserted.html new file mode 100644 index 0000000000..63d2c5a256 --- /dev/null +++ b/dom/security/test/csp/test_strict_dynamic_parser_inserted.html @@ -0,0 +1,94 @@ + + + + Bug 1299483 - CSP: Implement 'strict-dynamic' + + + + + + + + + + diff --git a/dom/security/test/csp/test_subframe_run_js_if_allowed.html b/dom/security/test/csp/test_subframe_run_js_if_allowed.html new file mode 100644 index 0000000000..fbf5a885cd --- /dev/null +++ b/dom/security/test/csp/test_subframe_run_js_if_allowed.html @@ -0,0 +1,33 @@ + + + + + Test for Bug 702439 + + + + + + + + diff --git a/dom/security/test/csp/test_svg_inline_style.html b/dom/security/test/csp/test_svg_inline_style.html new file mode 100644 index 0000000000..c05ca20467 --- /dev/null +++ b/dom/security/test/csp/test_svg_inline_style.html @@ -0,0 +1,135 @@ + + + + Bug 1262842: Test CSP inline style within svg image + + + + + + + + + + + + + + + diff --git a/dom/security/test/csp/test_uir_top_nav.html b/dom/security/test/csp/test_uir_top_nav.html new file mode 100644 index 0000000000..57005ba6f9 --- /dev/null +++ b/dom/security/test/csp/test_uir_top_nav.html @@ -0,0 +1,53 @@ + + + + Bug 1391011: Test uir for toplevel navigations + + + + + + + + + diff --git a/dom/security/test/csp/test_uir_windowwatcher.html b/dom/security/test/csp/test_uir_windowwatcher.html new file mode 100644 index 0000000000..f16b3c93a6 --- /dev/null +++ b/dom/security/test/csp/test_uir_windowwatcher.html @@ -0,0 +1,31 @@ + + + + + Bug 1529893 - Test upgrade-insecure-requests for opening window through nsWindowWatcher + + + + + + + + + + diff --git a/dom/security/test/csp/test_upgrade_insecure.html b/dom/security/test/csp/test_upgrade_insecure.html new file mode 100644 index 0000000000..0827b7f2df --- /dev/null +++ b/dom/security/test/csp/test_upgrade_insecure.html @@ -0,0 +1,192 @@ + + + + + Bug 1139297 - Implement CSP upgrade-insecure-requests directive + + + + + + + + + + diff --git a/dom/security/test/csp/test_upgrade_insecure_cors.html b/dom/security/test/csp/test_upgrade_insecure_cors.html new file mode 100644 index 0000000000..3ed53d8108 --- /dev/null +++ b/dom/security/test/csp/test_upgrade_insecure_cors.html @@ -0,0 +1,86 @@ + + + + + Bug 1139297 - Implement CSP upgrade-insecure-requests directive + + + + + + + + + + diff --git a/dom/security/test/csp/test_upgrade_insecure_docwrite_iframe.html b/dom/security/test/csp/test_upgrade_insecure_docwrite_iframe.html new file mode 100644 index 0000000000..dc6039ec35 --- /dev/null +++ b/dom/security/test/csp/test_upgrade_insecure_docwrite_iframe.html @@ -0,0 +1,54 @@ + + + + + Bug 1273430 - Test CSP upgrade-insecure-requests for doc.write(iframe) + + + + + + + + + + diff --git a/dom/security/test/csp/test_upgrade_insecure_loopback.html b/dom/security/test/csp/test_upgrade_insecure_loopback.html new file mode 100644 index 0000000000..f72f95215e --- /dev/null +++ b/dom/security/test/csp/test_upgrade_insecure_loopback.html @@ -0,0 +1,91 @@ + + + + + Bug 1447784 - Implement CSP upgrade-insecure-requests directive + + + + + + + + + + diff --git a/dom/security/test/csp/test_upgrade_insecure_navigation.html b/dom/security/test/csp/test_upgrade_insecure_navigation.html new file mode 100644 index 0000000000..5694deb15a --- /dev/null +++ b/dom/security/test/csp/test_upgrade_insecure_navigation.html @@ -0,0 +1,105 @@ + + + + Bug 1271173 - Missing spec on Upgrade Insecure Requests(Navigational Upgrades) + + + + + + + + + + + diff --git a/dom/security/test/csp/test_upgrade_insecure_navigation_redirect.html b/dom/security/test/csp/test_upgrade_insecure_navigation_redirect.html new file mode 100644 index 0000000000..17655e6316 --- /dev/null +++ b/dom/security/test/csp/test_upgrade_insecure_navigation_redirect.html @@ -0,0 +1,66 @@ + + + + Bug 1422284 - Upgrade insecure requests should only apply to top-level same-origin redirects + + + + + + + + + + diff --git a/dom/security/test/csp/test_upgrade_insecure_report_only.html b/dom/security/test/csp/test_upgrade_insecure_report_only.html new file mode 100644 index 0000000000..230d6a3e60 --- /dev/null +++ b/dom/security/test/csp/test_upgrade_insecure_report_only.html @@ -0,0 +1,98 @@ + + + + + Bug 1832249 - Consider report-only flag when upgrading insecure requests + + + + + + + + + + + diff --git a/dom/security/test/csp/test_upgrade_insecure_reporting.html b/dom/security/test/csp/test_upgrade_insecure_reporting.html new file mode 100644 index 0000000000..4966b8627e --- /dev/null +++ b/dom/security/test/csp/test_upgrade_insecure_reporting.html @@ -0,0 +1,69 @@ + + + + + Bug 1139297 - Implement CSP upgrade-insecure-requests directive + + + + + + + + + + diff --git a/dom/security/test/csp/test_websocket_localhost.html b/dom/security/test/csp/test_websocket_localhost.html new file mode 100644 index 0000000000..6bcc93fceb --- /dev/null +++ b/dom/security/test/csp/test_websocket_localhost.html @@ -0,0 +1,40 @@ + + + + + Bug 1729897: Allow unsecure websocket from localhost page with CSP: upgrade-insecure + + + + + + + + + + diff --git a/dom/security/test/csp/test_websocket_self.html b/dom/security/test/csp/test_websocket_self.html new file mode 100644 index 0000000000..3eae83bfbf --- /dev/null +++ b/dom/security/test/csp/test_websocket_self.html @@ -0,0 +1,61 @@ + + + + + Bug 1345615: Allow websocket schemes when using 'self' in CSP + + + + + + + + + + + diff --git a/dom/security/test/csp/test_win_open_blocked.html b/dom/security/test/csp/test_win_open_blocked.html new file mode 100644 index 0000000000..1335c9d272 --- /dev/null +++ b/dom/security/test/csp/test_win_open_blocked.html @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + diff --git a/dom/security/test/csp/test_worker_src.html b/dom/security/test/csp/test_worker_src.html new file mode 100644 index 0000000000..5aa8f7bc56 --- /dev/null +++ b/dom/security/test/csp/test_worker_src.html @@ -0,0 +1,105 @@ + + + + + Bug 1302667 - Test worker-src + + + + + + + + + diff --git a/dom/security/test/csp/test_xslt_inherits_csp.html b/dom/security/test/csp/test_xslt_inherits_csp.html new file mode 100644 index 0000000000..90e8372db1 --- /dev/null +++ b/dom/security/test/csp/test_xslt_inherits_csp.html @@ -0,0 +1,33 @@ + + + + + Bug 1597645: Make sure XSLT inherits the CSP r=ckerschb + + + + + + + + + + diff --git a/dom/security/test/csp/worker.sjs b/dom/security/test/csp/worker.sjs new file mode 100644 index 0000000000..9176b62cb5 --- /dev/null +++ b/dom/security/test/csp/worker.sjs @@ -0,0 +1,111 @@ +const SJS = "http://mochi.test:8888/tests/dom/security/test/csp/worker.sjs"; + +function createFetchWorker(url) { + return `fetch("${url}");`; +} + +function createXHRWorker(url) { + return ` + try { + var xhr = new XMLHttpRequest(); + xhr.open("GET", "${url}"); + xhr.send(); + } catch(ex) {} + `; +} + +function createImportScriptsWorker(url) { + return ` + try { + importScripts("${url}"); + } catch(ex) {} + `; +} + +function createChildWorkerURL(params) { + let url = SJS + "?" + params.toString(); + return `new Worker("${url}");`; +} + +function createChildWorkerBlob(params) { + let url = SJS + "?" + params.toString(); + return ` + try { + var xhr = new XMLHttpRequest(); + xhr.open("GET", "${url}"); + xhr.responseType = "blob"; + xhr.send(); + xhr.onload = () => { + new Worker(URL.createObjectURL(xhr.response));}; + } catch(ex) {} + `; +} + +function handleRequest(request, response) { + let params = new URLSearchParams(request.queryString); + + let id = params.get("id"); + let base = unescape(params.get("base")); + let child = params.has("child") ? params.get("child") : ""; + + //avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "application/javascript"); + + // Deliver the CSP policy encoded in the URL + if (params.has("csp")) { + response.setHeader( + "Content-Security-Policy", + unescape(params.get("csp")), + false + ); + } + + if (child) { + let childCsp = params.has("childCsp") ? params.get("childCsp") : ""; + params.delete("csp"); + params.delete("child"); + params.delete("childCsp"); + params.append("csp", childCsp); + + switch (child) { + case "blob": + response.write(createChildWorkerBlob(params)); + break; + + case "url": + response.write(createChildWorkerURL(params)); + break; + + default: + response.setStatusLine(request.httpVersion, 400, "Bad request"); + break; + } + + return; + } + + if (params.has("action")) { + switch (params.get("action")) { + case "fetch": + response.write(createFetchWorker(base + "?id=" + id)); + break; + + case "xhr": + response.write(createXHRWorker(base + "?id=" + id)); + break; + + case "importScripts": + response.write(createImportScriptsWorker(base + "?id=" + id)); + break; + + default: + response.setStatusLine(request.httpVersion, 400, "Bad request"); + break; + } + + return; + } + + response.write("I don't know action "); +} diff --git a/dom/security/test/csp/worker_helper.js b/dom/security/test/csp/worker_helper.js new file mode 100644 index 0000000000..3cadec9ea1 --- /dev/null +++ b/dom/security/test/csp/worker_helper.js @@ -0,0 +1,91 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +var _tests = []; +function addTest(test) { + _tests.push(test); +} + +function addAsyncTest(fn) { + _tests.push(() => fn().catch(ok.bind(null, false))); +} + +function runNextTest() { + if (!_tests.length) { + SimpleTest.finish(); + return; + } + const fn = _tests.shift(); + try { + fn(); + } catch (ex) { + info( + "Test function " + + (fn.name ? "'" + fn.name + "' " : "") + + "threw an exception: " + + ex + ); + } +} + +/** + * Helper to perform an XHR then blob response to create worker + */ +function doXHRGetBlob(uri) { + return new Promise(resolve => { + const xhr = new XMLHttpRequest(); + xhr.open("GET", uri); + xhr.responseType = "blob"; + xhr.addEventListener("load", function () { + is( + xhr.status, + 200, + "doXHRGetBlob load uri='" + uri + "' status=" + xhr.status + ); + resolve(xhr.response); + }); + xhr.send(); + }); +} + +function removeObserver(observer) { + SpecialPowers.removeObserver(observer, "specialpowers-http-notify-request"); + SpecialPowers.removeObserver(observer, "csp-on-violate-policy"); +} + +/** + * Helper to perform an assert to check if the request should be blocked or + * allowed by CSP + */ +function assertCSPBlock(url, shouldBlock) { + return new Promise((resolve, reject) => { + let observer = { + observe(subject, topic, data) { + if (topic === "specialpowers-http-notify-request") { + if (data == url) { + is(shouldBlock, false, "Should allow request uri='" + url); + removeObserver(observer); + resolve(); + } + } + + if (topic === "csp-on-violate-policy") { + let asciiSpec = SpecialPowers.getPrivilegedProps( + SpecialPowers.do_QueryInterface(subject, "nsIURI"), + "asciiSpec" + ); + if (asciiSpec == url) { + is(shouldBlock, true, "Should block request uri='" + url); + removeObserver(observer); + resolve(); + } + } + }, + }; + + SpecialPowers.addObserver(observer, "csp-on-violate-policy"); + SpecialPowers.addObserver(observer, "specialpowers-http-notify-request"); + }); +} diff --git a/dom/security/test/general/browser.toml b/dom/security/test/general/browser.toml new file mode 100644 index 0000000000..0f4ec5b224 --- /dev/null +++ b/dom/security/test/general/browser.toml @@ -0,0 +1,81 @@ +[DEFAULT] + +["browser_file_nonscript.js"] +support-files = [ + "file_loads_nonscript.html", + "file_nonscript", + "file_nonscript.xyz", + "file_nonscript.html", + "file_nonscript.txt", + "file_nonscript.json", + "file_script.js", +] + +["browser_restrict_privileged_about_script.js"] +# This test intentionally asserts when in debug builds. Let's rely on opt builds when in CI. +skip-if = ["debug"] +support-files = [ + "file_about_child.html", + "file_1767581.js", +] + +["browser_same_site_cookies_bug1748693.js"] +support-files = ["file_same_site_cookies_bug1748693.sjs"] + +["browser_test_assert_systemprincipal_documents.js"] +skip-if = ["!nightly_build"] +support-files = [ + "file_assert_systemprincipal_documents.html", + "file_assert_systemprincipal_documents_iframe.html", +] + +["browser_test_data_download.js"] +support-files = ["file_data_download.html"] + +["browser_test_data_text_csv.js"] +support-files = ["file_data_text_csv.html"] + +["browser_test_framing_error_pages.js"] +support-files = [ + "file_framing_error_pages_csp.html", + "file_framing_error_pages_xfo.html", + "file_framing_error_pages.sjs", +] + +["browser_test_gpc_privateBrowsingMode.js"] +support-files = [ + "file_empty.html", + "file_gpc_server.sjs", +] + +["browser_test_referrer_loadInOtherProcess.js"] + +["browser_test_report_blocking.js"] +support-files = [ + "file_framing_error_pages_xfo.html", + "file_framing_error_pages_csp.html", + "file_framing_error_pages.sjs", +] + +["browser_test_toplevel_data_navigations.js"] +skip-if = [ + "verify && debug && os == 'mac'", + "debug && (os == 'mac' || os == 'linux')", # Bug 1403815 +] +support-files = [ + "file_toplevel_data_navigations.sjs", + "file_toplevel_data_meta_redirect.html", +] + +["browser_test_view_image_data_navigation.js"] +support-files = [ + "file_view_image_data_navigation.html", + "file_view_bg_image_data_navigation.html", +] + +["browser_test_xfo_embed_object.js"] +support-files = [ + "file_framing_xfo_embed.html", + "file_framing_xfo_object.html", + "file_framing_xfo_embed_object.sjs", +] diff --git a/dom/security/test/general/browser_file_nonscript.js b/dom/security/test/general/browser_file_nonscript.js new file mode 100644 index 0000000000..95243c32a7 --- /dev/null +++ b/dom/security/test/general/browser_file_nonscript.js @@ -0,0 +1,38 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +add_task(async function test_fileurl_nonscript_load() { + await SpecialPowers.pushPrefEnv({ + set: [["security.block_fileuri_script_with_wrong_mime", true]], + }); + + let file = getChromeDir(getResolvedURI(gTestPath)); + file.append("file_loads_nonscript.html"); + let uriString = Services.io.newFileURI(file).spec; + + let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, uriString); + registerCleanupFunction(async function () { + BrowserTestUtils.removeTab(tab); + }); + + let counter = await SpecialPowers.spawn(tab.linkedBrowser, [], async () => { + Cu.exportFunction(Assert.equal.bind(Assert), content.window, { + defineAs: "equal", + }); + content.window.postMessage("run", "*"); + + await new Promise(resolve => { + content.window.addEventListener("message", event => { + if (event.data === "done") { + resolve(); + } + }); + }); + + return content.window.wrappedJSObject.counter; + }); + + is(counter, 1, "Only one script should have run"); +}); diff --git a/dom/security/test/general/browser_restrict_privileged_about_script.js b/dom/security/test/general/browser_restrict_privileged_about_script.js new file mode 100644 index 0000000000..0baa6e3d4d --- /dev/null +++ b/dom/security/test/general/browser_restrict_privileged_about_script.js @@ -0,0 +1,70 @@ +"use strict"; + +const kChildPage = getRootDirectory(gTestPath) + "file_about_child.html"; + +const kAboutPagesRegistered = BrowserTestUtils.registerAboutPage( + registerCleanupFunction, + "test-about-privileged-with-scripts", + kChildPage, + Ci.nsIAboutModule.ALLOW_SCRIPT | + Ci.nsIAboutModule.URI_MUST_LOAD_IN_CHILD | + Ci.nsIAboutModule.URI_CAN_LOAD_IN_PRIVILEGEDABOUT_PROCESS | + Ci.nsIAboutModule.URI_SAFE_FOR_UNTRUSTED_CONTENT | + Ci.nsIAboutModule.IS_SECURE_CHROME_UI +); + +add_task(async function test_principal_click() { + await kAboutPagesRegistered; + await SpecialPowers.pushPrefEnv({ + set: [["dom.security.skip_about_page_has_csp_assert", true]], + }); + await BrowserTestUtils.withNewTab( + "about:test-about-privileged-with-scripts", + async function (browser) { + // Wait for page to fully load + info("Waiting for tab to be loaded.."); + // let's look into the fully loaded about page + await SpecialPowers.spawn( + gBrowser.selectedBrowser, + [], + async function () { + let channel = content.docShell.currentDocumentChannel; + is( + channel.originalURI.asciiSpec, + "about:test-about-privileged-with-scripts", + "sanity check - make sure we test the principal for the correct URI" + ); + + let triggeringPrincipal = channel.loadInfo.triggeringPrincipal; + ok( + triggeringPrincipal.isSystemPrincipal, + "loading about: from privileged page must have a triggering of System" + ); + + let contentPolicyType = channel.loadInfo.externalContentPolicyType; + is( + contentPolicyType, + Ci.nsIContentPolicy.TYPE_DOCUMENT, + "sanity check - loading a top level document" + ); + + let loadingPrincipal = channel.loadInfo.loadingPrincipal; + is( + loadingPrincipal, + null, + "sanity check - load of TYPE_DOCUMENT must have a null loadingPrincipal" + ); + ok( + !content.document.nodePrincipal.isSystemPrincipal, + "sanity check - loaded about page does not have the system principal" + ); + isnot( + content.testResult, + "fail-script-was-loaded", + "The script from https://example.com shouldn't work in an about: page." + ); + } + ); + } + ); +}); diff --git a/dom/security/test/general/browser_same_site_cookies_bug1748693.js b/dom/security/test/general/browser_same_site_cookies_bug1748693.js new file mode 100644 index 0000000000..66a7927889 --- /dev/null +++ b/dom/security/test/general/browser_same_site_cookies_bug1748693.js @@ -0,0 +1,61 @@ +"use strict"; + +const HTTPS_PATH = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "https://example.com" +); +const HTTP_PATH = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + // Disable eslint, since we explicitly need a insecure URL here for this test. + // eslint-disable-next-line @microsoft/sdl/no-insecure-url + "http://example.com" +); + +function checkCookies(expectedCookies = {}) { + info(JSON.stringify(expectedCookies)); + return SpecialPowers.spawn( + gBrowser.selectedBrowser, + [expectedCookies], + async function (expectedCookies) { + let cookies = content.document.getElementById("msg").innerHTML; + info(cookies); + for (const [cookie, expected] of Object.entries(expectedCookies)) { + if (expected) { + ok(cookies.includes(cookie), `${cookie} should be sent`); + } else { + ok(!cookies.includes(cookie), `${cookie} should not be sent`); + } + } + } + ); +} + +add_task(async function bug1748693() { + waitForExplicitFinish(); + + // HTTPS-First would interfere with this test. We want to check wether + // cookies orignally set on a secure site without a "Secure" attribute + // get loaded on a insecure site. For that, we need to visit a + // insecure site, which would otherwise be upgraded by HTTPS-First. + await SpecialPowers.pushPrefEnv({ + set: [["dom.security.https_first", false]], + }); + + let loaded = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser); + BrowserTestUtils.startLoadingURIString( + gBrowser, + `${HTTPS_PATH}file_same_site_cookies_bug1748693.sjs?setcookies` + ); + await loaded; + + loaded = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser); + BrowserTestUtils.startLoadingURIString( + gBrowser, + `${HTTP_PATH}file_same_site_cookies_bug1748693.sjs` + ); + await loaded; + + await checkCookies({ auth: true, auth_secure: false }); + + finish(); +}); diff --git a/dom/security/test/general/browser_test_assert_systemprincipal_documents.js b/dom/security/test/general/browser_test_assert_systemprincipal_documents.js new file mode 100644 index 0000000000..8804e85b2c --- /dev/null +++ b/dom/security/test/general/browser_test_assert_systemprincipal_documents.js @@ -0,0 +1,41 @@ +//"use strict" + +const kTestPath = getRootDirectory(gTestPath); +const kTestURI = kTestPath + "file_assert_systemprincipal_documents.html"; + +add_setup(async function () { + // We expect the assertion in function + // CheckSystemPrincipalLoads as defined in + // file dom/security/nsContentSecurityManager.cpp + SimpleTest.expectAssertions(1); + + await SpecialPowers.pushPrefEnv({ + set: [ + ["security.disallow_non_local_systemprincipal_in_tests", true], + ["security.allow_unsafe_parent_loads", true], + ], + }); +}); + +add_task(async function open_test_iframe_in_tab() { + // This looks at the iframe (load type SUBDOCUMENT) + await BrowserTestUtils.withNewTab( + { gBrowser, url: kTestURI }, + async browser => { + await SpecialPowers.spawn(browser, [], async function () { + let outerPrincipal = content.document.nodePrincipal; + ok( + outerPrincipal.isSystemPrincipal, + "Sanity: Using SystemPrincipal for test file on chrome://" + ); + const iframeDoc = + content.document.getElementById("testframe").contentDocument; + is( + iframeDoc.body.innerHTML, + "", + "iframe with systemprincipal should be empty document" + ); + }); + } + ); +}); diff --git a/dom/security/test/general/browser_test_data_download.js b/dom/security/test/general/browser_test_data_download.js new file mode 100644 index 0000000000..df5a8aeac4 --- /dev/null +++ b/dom/security/test/general/browser_test_data_download.js @@ -0,0 +1,113 @@ +"use strict"; + +const kTestPath = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "http://example.com" +); +const kTestURI = kTestPath + "file_data_download.html"; + +function addWindowListener(aURL) { + return new Promise(resolve => { + Services.wm.addListener({ + onOpenWindow(aXULWindow) { + info("window opened, waiting for focus"); + Services.wm.removeListener(this); + var domwindow = aXULWindow.docShell.domWindow; + waitForFocus(function () { + is( + domwindow.document.location.href, + aURL, + "should have seen the right window open" + ); + resolve(domwindow); + }, domwindow); + }, + onCloseWindow(aXULWindow) {}, + }); + }); +} + +function waitDelay(delay) { + return new Promise((resolve, reject) => { + /* eslint-disable mozilla/no-arbitrary-setTimeout */ + window.setTimeout(resolve, delay); + }); +} + +function promisePanelOpened() { + if (DownloadsPanel.panel && DownloadsPanel.panel.state == "open") { + return Promise.resolve(); + } + return BrowserTestUtils.waitForEvent(DownloadsPanel.panel, "popupshown"); +} + +add_task(async function test_with_downloads_pref_disabled() { + waitForExplicitFinish(); + await SpecialPowers.pushPrefEnv({ + set: [ + ["security.data_uri.block_toplevel_data_uri_navigations", true], + ["browser.download.always_ask_before_handling_new_types", true], + ], + }); + let windowPromise = addWindowListener( + "chrome://mozapps/content/downloads/unknownContentType.xhtml" + ); + BrowserTestUtils.startLoadingURIString(gBrowser, kTestURI); + let win = await windowPromise; + + is( + win.document.getElementById("location").value, + "data-foo.html", + "file name of download should match" + ); + + let mainWindowActivated = BrowserTestUtils.waitForEvent(window, "activate"); + await BrowserTestUtils.closeWindow(win); + await mainWindowActivated; +}); + +add_task(async function test_with_always_ask_pref_disabled() { + waitForExplicitFinish(); + await SpecialPowers.pushPrefEnv({ + set: [ + ["security.data_uri.block_toplevel_data_uri_navigations", true], + ["browser.download.always_ask_before_handling_new_types", false], + ], + }); + let downloadsPanelPromise = promisePanelOpened(); + let downloadsPromise = Downloads.getList(Downloads.PUBLIC); + + BrowserTestUtils.startLoadingURIString(gBrowser, kTestURI); + // wait until downloadsPanel opens before continuing with test + await downloadsPanelPromise; + let downloadList = await downloadsPromise; + + is(DownloadsPanel.isPanelShowing, true, "DownloadsPanel should be open."); + is( + downloadList._downloads.length, + 1, + "File should be successfully downloaded." + ); + + let [download] = downloadList._downloads; + is(download.contentType, "text/html", "File contentType should be correct."); + is( + download.source.url, + "data:text/html,data download", + "File name should be correct." + ); + + info("cleaning up downloads"); + try { + if (Services.appinfo.OS === "WINNT") { + // We need to make the file writable to delete it on Windows. + await IOUtils.setPermissions(download.target.path, 0o600); + } + await IOUtils.remove(download.target.path); + } catch (error) { + info("The file " + download.target.path + " is not removed, " + error); + } + + await downloadList.remove(download); + await download.finalize(); +}); diff --git a/dom/security/test/general/browser_test_data_text_csv.js b/dom/security/test/general/browser_test_data_text_csv.js new file mode 100644 index 0000000000..9855ddce46 --- /dev/null +++ b/dom/security/test/general/browser_test_data_text_csv.js @@ -0,0 +1,108 @@ +"use strict"; + +const kTestPath = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "http://example.com" +); +const kTestURI = kTestPath + "file_data_text_csv.html"; + +function addWindowListener(aURL, aCallback) { + return new Promise(resolve => { + Services.wm.addListener({ + onOpenWindow(aXULWindow) { + info("window opened, waiting for focus"); + Services.wm.removeListener(this); + var domwindow = aXULWindow.docShell.domWindow; + waitForFocus(function () { + is( + domwindow.document.location.href, + aURL, + "should have seen the right window open" + ); + resolve(domwindow); + }, domwindow); + }, + onCloseWindow(aXULWindow) {}, + }); + }); +} + +function promisePanelOpened() { + if (DownloadsPanel.panel && DownloadsPanel.panel.state == "open") { + return Promise.resolve(); + } + return BrowserTestUtils.waitForEvent(DownloadsPanel.panel, "popupshown"); +} + +add_task(async function test_with_pref_enabled() { + await SpecialPowers.pushPrefEnv({ + set: [ + ["security.data_uri.block_toplevel_data_uri_navigations", true], + ["browser.download.always_ask_before_handling_new_types", true], + ], + }); + + let windowPromise = addWindowListener( + "chrome://mozapps/content/downloads/unknownContentType.xhtml" + ); + BrowserTestUtils.startLoadingURIString(gBrowser, kTestURI); + let win = await windowPromise; + + let expectedValue = "Untitled.csv"; + is( + win.document.getElementById("location").value, + expectedValue, + "file name of download should match" + ); + let mainWindowActivated = BrowserTestUtils.waitForEvent(window, "activate"); + await BrowserTestUtils.closeWindow(win); + await mainWindowActivated; +}); + +add_task(async function test_with_pref_disabled() { + await SpecialPowers.pushPrefEnv({ + set: [ + ["security.data_uri.block_toplevel_data_uri_navigations", true], + ["browser.download.always_ask_before_handling_new_types", false], + ], + }); + let downloadsPanelPromise = promisePanelOpened(); + let downloadsPromise = Downloads.getList(Downloads.PUBLIC); + let sourceURLBit = "text/csv;foo,bar,foobar"; + + info("Loading URI for pref enabled"); + BrowserTestUtils.startLoadingURIString(gBrowser, kTestURI); + info("Waiting for downloads panel to open"); + await downloadsPanelPromise; + info("Getting downloads info after opening downloads panel"); + let downloadList = await downloadsPromise; + + is(DownloadsPanel.isPanelShowing, true, "DownloadsPanel should be open."); + is( + downloadList._downloads.length, + 1, + "File should be successfully downloaded." + ); + + let [download] = downloadList._downloads; + is(download.contentType, "text/csv", "File contentType should be correct."); + is( + download.source.url, + `data:${sourceURLBit}`, + "File name should be correct." + ); + + info("Cleaning up downloads"); + try { + if (Services.appinfo.OS === "WINNT") { + // We need to make the file writable to delete it on Windows. + await IOUtils.setPermissions(download.target.path, 0o600); + } + await IOUtils.remove(download.target.path); + } catch (ex) { + info("The file " + download.target.path + " is not removed, " + ex); + } + + await downloadList.remove(download); + await download.finalize(); +}); diff --git a/dom/security/test/general/browser_test_framing_error_pages.js b/dom/security/test/general/browser_test_framing_error_pages.js new file mode 100644 index 0000000000..9fc10f34c7 --- /dev/null +++ b/dom/security/test/general/browser_test_framing_error_pages.js @@ -0,0 +1,53 @@ +"use strict"; + +const kTestPath = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "https://example.com" +); +const kTestXFrameOptionsURI = kTestPath + "file_framing_error_pages_xfo.html"; +const kTestXFrameOptionsURIFrame = + kTestPath + "file_framing_error_pages.sjs?xfo"; + +const kTestFrameAncestorsURI = kTestPath + "file_framing_error_pages_csp.html"; +const kTestFrameAncestorsURIFrame = + kTestPath + "file_framing_error_pages.sjs?csp"; + +add_task(async function open_test_xfo_error_page() { + await BrowserTestUtils.withNewTab("about:blank", async function (browser) { + let loaded = BrowserTestUtils.browserLoaded( + browser, + true, + kTestXFrameOptionsURIFrame, + true + ); + BrowserTestUtils.startLoadingURIString(browser, kTestXFrameOptionsURI); + await loaded; + + await SpecialPowers.spawn(browser, [], async function () { + const iframeDoc = + content.document.getElementById("testframe").contentDocument; + let errorPage = iframeDoc.body.innerHTML; + ok(errorPage.includes("csp-xfo-error-title"), "xfo error page correct"); + }); + }); +}); + +add_task(async function open_test_csp_frame_ancestor_error_page() { + await BrowserTestUtils.withNewTab("about:blank", async function (browser) { + let loaded = BrowserTestUtils.browserLoaded( + browser, + true, + kTestFrameAncestorsURIFrame, + true + ); + BrowserTestUtils.startLoadingURIString(browser, kTestFrameAncestorsURI); + await loaded; + + await SpecialPowers.spawn(browser, [], async function () { + const iframeDoc = + content.document.getElementById("testframe").contentDocument; + let errorPage = iframeDoc.body.innerHTML; + ok(errorPage.includes("csp-xfo-error-title"), "csp error page correct"); + }); + }); +}); diff --git a/dom/security/test/general/browser_test_gpc_privateBrowsingMode.js b/dom/security/test/general/browser_test_gpc_privateBrowsingMode.js new file mode 100644 index 0000000000..5c056395a8 --- /dev/null +++ b/dom/security/test/general/browser_test_gpc_privateBrowsingMode.js @@ -0,0 +1,67 @@ +"use strict"; + +const kTestPath = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "https://example.com" +); +const kTestURI = kTestPath + "file_empty.html"; + +add_task(async function test_privateModeGPCEnabled() { + await SpecialPowers.pushPrefEnv({ + set: [ + ["privacy.globalprivacycontrol.enabled", false], + ["privacy.globalprivacycontrol.pbmode.enabled", true], + ["privacy.globalprivacycontrol.functionality.enabled", true], + ], + }); + let win = await BrowserTestUtils.openNewBrowserWindow({ private: true }); + let tab = await BrowserTestUtils.openNewForegroundTab(win.gBrowser, kTestURI); + let browser = win.gBrowser.getBrowserForTab(tab); + let result = await SpecialPowers.spawn(browser, [], async function () { + return content.window + .fetch("file_gpc_server.sjs") + .then(response => response.text()) + .then(response => { + is(response, "true", "GPC header provided"); + is( + content.window.navigator.globalPrivacyControl, + true, + "GPC on navigator" + ); + // Bug 1320796: Service workers are not enabled in PB Mode + return true; + }); + }); + ok(result, "Promise chain resolves in content process"); + win.close(); +}); + +add_task(async function test_privateModeGPCDisabled() { + await SpecialPowers.pushPrefEnv({ + set: [ + ["privacy.globalprivacycontrol.enabled", false], + ["privacy.globalprivacycontrol.pbmode.enabled", false], + ["privacy.globalprivacycontrol.functionality.enabled", true], + ], + }); + let win = await BrowserTestUtils.openNewBrowserWindow({ private: true }); + let tab = await BrowserTestUtils.openNewForegroundTab(win.gBrowser, kTestURI); + let browser = win.gBrowser.getBrowserForTab(tab); + let result = await SpecialPowers.spawn(browser, [], async function () { + return content.window + .fetch("file_gpc_server.sjs") + .then(response => response.text()) + .then(response => { + isnot(response, "true", "GPC header provided"); + isnot( + content.window.navigator.globalPrivacyControl, + true, + "GPC on navigator" + ); + // Bug 1320796: Service workers are not enabled in PB Mode + return true; + }); + }); + ok(result, "Promise chain resolves in content process"); + win.close(); +}); diff --git a/dom/security/test/general/browser_test_referrer_loadInOtherProcess.js b/dom/security/test/general/browser_test_referrer_loadInOtherProcess.js new file mode 100644 index 0000000000..7da60b727d --- /dev/null +++ b/dom/security/test/general/browser_test_referrer_loadInOtherProcess.js @@ -0,0 +1,156 @@ +const TEST_PAGE = + "https://example.org/browser/browser/base/content/test/general/dummy_page.html"; +const TEST_REFERRER = "http://mochi.test:8888/"; + +const ReferrerInfo = Components.Constructor( + "@mozilla.org/referrer-info;1", + "nsIReferrerInfo", + "init" +); + +let referrerInfo = new ReferrerInfo( + Ci.nsIReferrerInfo.ORIGIN, + true, + Services.io.newURI(TEST_REFERRER) +); +let deReferrerInfo = E10SUtils.serializeReferrerInfo(referrerInfo); + +var checkResult = async function (isRemote, browserKey, uri) { + is( + gBrowser.selectedBrowser.isRemoteBrowser, + isRemote, + "isRemoteBrowser should be correct" + ); + + is( + gBrowser.selectedBrowser.permanentKey, + browserKey, + "browser.permanentKey should be correct" + ); + + if (SpecialPowers.Services.appinfo.sessionHistoryInParent) { + let sessionHistory = + gBrowser.selectedBrowser.browsingContext.sessionHistory; + let entry = sessionHistory.getEntryAtIndex(sessionHistory.count - 1); + let args = { uri, referrerInfo: deReferrerInfo, isRemote }; + Assert.equal(entry.URI.spec, args.uri, "Uri should be correct"); + + // Main process like about:mozilla does not trigger the real network request. + // So we don't store referrerInfo in sessionHistory in that case. + // Besides, the referrerInfo stored in sessionHistory was computed, we only + // check pre-computed things. + if (args.isRemote) { + let resultReferrerInfo = entry.referrerInfo; + let expectedReferrerInfo = E10SUtils.deserializeReferrerInfo( + args.referrerInfo + ); + + Assert.equal( + resultReferrerInfo.originalReferrer.spec, + expectedReferrerInfo.originalReferrer.spec, + "originalReferrer should be correct" + ); + Assert.equal( + resultReferrerInfo.sendReferrer, + expectedReferrerInfo.sendReferrer, + "sendReferrer should be correct" + ); + Assert.equal( + resultReferrerInfo.referrerPolicy, + expectedReferrerInfo.referrerPolicy, + "referrerPolicy should be correct" + ); + } else { + Assert.equal(entry.referrerInfo, null, "ReferrerInfo should be correct"); + } + + return; + } + + await SpecialPowers.spawn( + gBrowser.selectedBrowser, + [{ uri, referrerInfo: deReferrerInfo, isRemote }], + async function (args) { + let webNav = content.docShell.QueryInterface(Ci.nsIWebNavigation); + let sessionHistory = webNav.sessionHistory; + let entry = sessionHistory.legacySHistory.getEntryAtIndex( + sessionHistory.count - 1 + ); + + var { E10SUtils } = SpecialPowers.ChromeUtils.importESModule( + "resource://gre/modules/E10SUtils.sys.mjs" + ); + + Assert.equal(entry.URI.spec, args.uri, "Uri should be correct"); + + // Main process like about:mozilla does not trigger the real network request. + // So we don't store referrerInfo in sessionHistory in that case. + // Besides, the referrerInfo stored in sessionHistory was computed, we only + // check pre-computed things. + if (args.isRemote) { + let resultReferrerInfo = entry.referrerInfo; + let expectedReferrerInfo = E10SUtils.deserializeReferrerInfo( + args.referrerInfo + ); + + Assert.equal( + resultReferrerInfo.originalReferrer.spec, + expectedReferrerInfo.originalReferrer.spec, + "originalReferrer should be correct" + ); + Assert.equal( + resultReferrerInfo.sendReferrer, + expectedReferrerInfo.sendReferrer, + "sendReferrer should be correct" + ); + Assert.equal( + resultReferrerInfo.referrerPolicy, + expectedReferrerInfo.referrerPolicy, + "referrerPolicy should be correct" + ); + } else { + Assert.equal( + entry.referrerInfo, + null, + "ReferrerInfo should be correct" + ); + } + } + ); +}; +var waitForLoad = async function (uri) { + info("waitForLoad " + uri); + let loadURIOptions = { + triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(), + referrerInfo, + }; + gBrowser.selectedBrowser.webNavigation.loadURI( + Services.io.newURI(uri), + loadURIOptions + ); + + await BrowserTestUtils.browserStopped(gBrowser, uri); +}; + +// Tests referrerInfo when navigating from a page in the remote process to main +// process and vice versa. +add_task(async function test_navigation() { + // Navigate from non remote to remote + gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, "about:blank"); + let testURI = TEST_PAGE; + let { permanentKey } = gBrowser.selectedBrowser; + await waitForLoad(testURI); + await checkResult(true, permanentKey, testURI); + gBrowser.removeCurrentTab(); + + // Navigate from remote to non-remote + gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, TEST_PAGE); + // Wait for the non-blank page to finish loading + await BrowserTestUtils.browserStopped(gBrowser, TEST_PAGE); + testURI = "about:mozilla"; + permanentKey = gBrowser.selectedBrowser.permanentKey; + await waitForLoad(testURI); + await checkResult(false, permanentKey, testURI); + + gBrowser.removeCurrentTab(); +}); diff --git a/dom/security/test/general/browser_test_report_blocking.js b/dom/security/test/general/browser_test_report_blocking.js new file mode 100644 index 0000000000..ebd7514097 --- /dev/null +++ b/dom/security/test/general/browser_test_report_blocking.js @@ -0,0 +1,218 @@ +"use strict"; + +const { TelemetryArchiveTesting } = ChromeUtils.importESModule( + "resource://testing-common/TelemetryArchiveTesting.sys.mjs" +); + +const kTestPath = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "https://example.com" +); + +const kTestXFrameOptionsURI = kTestPath + "file_framing_error_pages_xfo.html"; +const kTestCspURI = kTestPath + "file_framing_error_pages_csp.html"; +const kTestXFrameOptionsURIFrame = + kTestPath + "file_framing_error_pages.sjs?xfo"; +const kTestCspURIFrame = kTestPath + "file_framing_error_pages.sjs?csp"; + +const kTestExpectedPingXFO = [ + [["payload", "error_type"], "xfo"], + [["payload", "xfo_header"], "deny"], + [["payload", "csp_header"], ""], + [["payload", "frame_hostname"], "example.com"], + [["payload", "top_hostname"], "example.com"], + [ + ["payload", "frame_uri"], + "https://example.com/browser/dom/security/test/general/file_framing_error_pages.sjs", + ], + [ + ["payload", "top_uri"], + "https://example.com/browser/dom/security/test/general/file_framing_error_pages_xfo.html", + ], +]; + +const kTestExpectedPingCSP = [ + [["payload", "error_type"], "csp"], + [["payload", "xfo_header"], ""], + [["payload", "csp_header"], "'none'"], + [["payload", "frame_hostname"], "example.com"], + [["payload", "top_hostname"], "example.com"], + [ + ["payload", "frame_uri"], + "https://example.com/browser/dom/security/test/general/file_framing_error_pages.sjs", + ], + [ + ["payload", "top_uri"], + "https://example.com/browser/dom/security/test/general/file_framing_error_pages_csp.html", + ], +]; + +const TEST_CASES = [ + { + type: "xfo", + test_uri: kTestXFrameOptionsURI, + frame_uri: kTestXFrameOptionsURIFrame, + expected_ping: kTestExpectedPingXFO, + }, + { + type: "csp", + test_uri: kTestCspURI, + frame_uri: kTestCspURIFrame, + expected_ping: kTestExpectedPingCSP, + }, +]; + +add_setup(async function () { + Services.telemetry.setEventRecordingEnabled("security.ui.xfocsperror", true); + + await SpecialPowers.pushPrefEnv({ + set: [ + ["security.xfocsp.errorReporting.enabled", true], + ["security.xfocsp.errorReporting.automatic", false], + ], + }); +}); + +add_task(async function testReportingCases() { + for (const test of TEST_CASES) { + await testReporting(test); + } +}); + +async function testReporting(test) { + // Clear telemetry event before testing. + Services.telemetry.clearEvents(); + + let telemetryChecker = new TelemetryArchiveTesting.Checker(); + await telemetryChecker.promiseInit(); + + let tab = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + "about:blank" + ); + let browser = tab.linkedBrowser; + + let loaded = BrowserTestUtils.browserLoaded( + browser, + true, + test.frame_uri, + true + ); + BrowserTestUtils.startLoadingURIString(browser, test.test_uri); + await loaded; + + let { type } = test; + + let frameBC = await SpecialPowers.spawn(browser, [], async _ => { + const iframe = content.document.getElementById("testframe"); + return iframe.browsingContext; + }); + + await SpecialPowers.spawn(frameBC, [type], async obj => { + // Wait until the reporting UI is visible. + await ContentTaskUtils.waitForCondition(() => { + let reportUI = content.document.getElementById("blockingErrorReporting"); + return ContentTaskUtils.isVisible(reportUI); + }); + + let reportCheckBox = content.document.getElementById( + "automaticallyReportBlockingInFuture" + ); + is( + reportCheckBox.checked, + false, + "The checkbox of the reporting ui should be not checked." + ); + + // Click on the checkbox. + await EventUtils.synthesizeMouseAtCenter(reportCheckBox, {}, content); + }); + BrowserTestUtils.removeTab(tab); + + // Open the error page again + tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank"); + browser = tab.linkedBrowser; + + loaded = BrowserTestUtils.browserLoaded(browser, true, test.frame_uri, true); + BrowserTestUtils.startLoadingURIString(browser, test.test_uri); + await loaded; + + frameBC = await SpecialPowers.spawn(browser, [], async _ => { + const iframe = content.document.getElementById("testframe"); + return iframe.browsingContext; + }); + + await SpecialPowers.spawn(frameBC, [], async _ => { + // Wait until the reporting UI is visible. + await ContentTaskUtils.waitForCondition(() => { + let reportUI = content.document.getElementById("blockingErrorReporting"); + return ContentTaskUtils.isVisible(reportUI); + }); + + let reportCheckBox = content.document.getElementById( + "automaticallyReportBlockingInFuture" + ); + is( + reportCheckBox.checked, + true, + "The checkbox of the reporting ui should be checked." + ); + + // Click on the checkbox again to disable the reporting. + await EventUtils.synthesizeMouseAtCenter(reportCheckBox, {}, content); + + is( + reportCheckBox.checked, + false, + "The checkbox of the reporting ui should be unchecked." + ); + }); + BrowserTestUtils.removeTab(tab); + + // Open the error page again to see if the reporting is disabled. + tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank"); + browser = tab.linkedBrowser; + + loaded = BrowserTestUtils.browserLoaded(browser, true, test.frame_uri, true); + BrowserTestUtils.startLoadingURIString(browser, test.test_uri); + await loaded; + + frameBC = await SpecialPowers.spawn(browser, [], async _ => { + const iframe = content.document.getElementById("testframe"); + return iframe.browsingContext; + }); + + await SpecialPowers.spawn(frameBC, [], async _ => { + // Wait until the reporting UI is visible. + await ContentTaskUtils.waitForCondition(() => { + let reportUI = content.document.getElementById("blockingErrorReporting"); + return ContentTaskUtils.isVisible(reportUI); + }); + + let reportCheckBox = content.document.getElementById( + "automaticallyReportBlockingInFuture" + ); + is( + reportCheckBox.checked, + false, + "The checkbox of the reporting ui should be unchecked." + ); + }); + BrowserTestUtils.removeTab(tab); + + // Finally, check if the ping has been archived. + await new Promise(resolve => { + telemetryChecker + .promiseFindPing("xfocsp-error-report", test.expected_ping) + .then( + found => { + ok(found, "Telemetry ping submitted successfully"); + resolve(); + }, + err => { + ok(false, "Exception finding telemetry ping: " + err); + resolve(); + } + ); + }); +} diff --git a/dom/security/test/general/browser_test_toplevel_data_navigations.js b/dom/security/test/general/browser_test_toplevel_data_navigations.js new file mode 100644 index 0000000000..0e006f1fd2 --- /dev/null +++ b/dom/security/test/general/browser_test_toplevel_data_navigations.js @@ -0,0 +1,70 @@ +/* eslint-disable mozilla/no-arbitrary-setTimeout */ + +"use strict"; + +const kDataBody = "toplevel navigation to data: URI allowed"; +const kDataURI = "data:text/html," + kDataBody + ""; +const kTestPath = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "http://example.com" +); +const kRedirectURI = kTestPath + "file_toplevel_data_navigations.sjs"; +const kMetaRedirectURI = kTestPath + "file_toplevel_data_meta_redirect.html"; + +add_task(async function test_nav_data_uri() { + await SpecialPowers.pushPrefEnv({ + set: [["security.data_uri.block_toplevel_data_uri_navigations", true]], + }); + await BrowserTestUtils.withNewTab(kDataURI, async function (browser) { + await SpecialPowers.spawn( + gBrowser.selectedBrowser, + [{ kDataBody }], + async function ({ kDataBody }) { + // eslint-disable-line + is( + content.document.body.innerHTML, + kDataBody, + "data: URI navigation from system should be allowed" + ); + } + ); + }); +}); + +add_task(async function test_nav_data_uri_redirect() { + await SpecialPowers.pushPrefEnv({ + set: [["security.data_uri.block_toplevel_data_uri_navigations", true]], + }); + let tab = BrowserTestUtils.addTab(gBrowser, kRedirectURI); + registerCleanupFunction(async function () { + BrowserTestUtils.removeTab(tab); + }); + // wait to make sure data: URI did not load before checking that it got blocked + await new Promise(resolve => setTimeout(resolve, 500)); + await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async function () { + is( + content.document.body.innerHTML, + "", + "data: URI navigation after server redirect should be blocked" + ); + }); +}); + +add_task(async function test_nav_data_uri_meta_redirect() { + await SpecialPowers.pushPrefEnv({ + set: [["security.data_uri.block_toplevel_data_uri_navigations", true]], + }); + let tab = BrowserTestUtils.addTab(gBrowser, kMetaRedirectURI); + registerCleanupFunction(async function () { + BrowserTestUtils.removeTab(tab); + }); + // wait to make sure data: URI did not load before checking that it got blocked + await new Promise(resolve => setTimeout(resolve, 500)); + await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async function () { + is( + content.document.body.innerHTML, + "", + "data: URI navigation after meta redirect should be blocked" + ); + }); +}); diff --git a/dom/security/test/general/browser_test_view_image_data_navigation.js b/dom/security/test/general/browser_test_view_image_data_navigation.js new file mode 100644 index 0000000000..90aace1e3e --- /dev/null +++ b/dom/security/test/general/browser_test_view_image_data_navigation.js @@ -0,0 +1,71 @@ +"use strict"; + +add_task(async function test_principal_right_click_open_link_in_new_tab() { + await SpecialPowers.pushPrefEnv({ + set: [["security.data_uri.block_toplevel_data_uri_navigations", true]], + }); + + const TEST_PAGE = + getRootDirectory(gTestPath) + "file_view_image_data_navigation.html"; + + await BrowserTestUtils.withNewTab(TEST_PAGE, async function (browser) { + let loadPromise = BrowserTestUtils.waitForNewTab(gBrowser, null, true); + + // simulate right-click->view-image + BrowserTestUtils.waitForEvent(document, "popupshown", false, event => { + // These are operations that must be executed synchronously with the event. + document.getElementById("context-viewimage").doCommand(); + event.target.hidePopup(); + return true; + }); + BrowserTestUtils.synthesizeMouseAtCenter( + "#testimage", + { type: "contextmenu", button: 2 }, + gBrowser.selectedBrowser + ); + let tab = await loadPromise; + + let spec = tab.linkedBrowser.currentURI.spec; + ok( + spec.startsWith("data:image/svg+xml;"), + "data:image/svg navigation allowed through right-click view-image" + ); + + gBrowser.removeTab(tab); + }); +}); + +add_task(async function test_right_click_open_bg_image() { + await SpecialPowers.pushPrefEnv({ + set: [["security.data_uri.block_toplevel_data_uri_navigations", true]], + }); + + const TEST_PAGE = + getRootDirectory(gTestPath) + "file_view_bg_image_data_navigation.html"; + + await BrowserTestUtils.withNewTab(TEST_PAGE, async function (browser) { + let loadPromise = BrowserTestUtils.waitForNewTab(gBrowser, null, true); + + // simulate right-click->view-image + BrowserTestUtils.waitForEvent(document, "popupshown", false, event => { + // These are operations that must be executed synchronously with the event. + document.getElementById("context-viewimage").doCommand(); + event.target.hidePopup(); + return true; + }); + BrowserTestUtils.synthesizeMouseAtCenter( + "#testbody", + { type: "contextmenu", button: 2 }, + gBrowser.selectedBrowser + ); + let tab = await loadPromise; + + let spec = tab.linkedBrowser.currentURI.spec; + ok( + spec.startsWith("data:image/svg+xml;"), + "data:image/svg navigation allowed through right-click view-image with background image" + ); + + gBrowser.removeTab(tab); + }); +}); diff --git a/dom/security/test/general/browser_test_xfo_embed_object.js b/dom/security/test/general/browser_test_xfo_embed_object.js new file mode 100644 index 0000000000..bcc48b984c --- /dev/null +++ b/dom/security/test/general/browser_test_xfo_embed_object.js @@ -0,0 +1,41 @@ +"use strict"; + +const kTestPath = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "https://example.com" +); +const kTestXFOEmbedURI = kTestPath + "file_framing_xfo_embed.html"; +const kTestXFOObjectURI = kTestPath + "file_framing_xfo_object.html"; + +const errorMessage = `The loading of “https://example.com/browser/dom/security/test/general/file_framing_xfo_embed_object.sjs” in a frame is denied by “X-Frame-Options“ directive set to “deny“`; + +let xfoBlocked = false; + +function onXFOMessage(msgObj) { + const message = msgObj.message; + + if (message.includes(errorMessage)) { + ok(true, "XFO error message logged"); + xfoBlocked = true; + } +} + +add_task(async function open_test_xfo_embed_blocked() { + xfoBlocked = false; + await BrowserTestUtils.withNewTab("about:blank", async function (browser) { + Services.console.registerListener(onXFOMessage); + BrowserTestUtils.startLoadingURIString(browser, kTestXFOEmbedURI); + await BrowserTestUtils.waitForCondition(() => xfoBlocked); + Services.console.unregisterListener(onXFOMessage); + }); +}); + +add_task(async function open_test_xfo_object_blocked() { + xfoBlocked = false; + await BrowserTestUtils.withNewTab("about:blank", async function (browser) { + Services.console.registerListener(onXFOMessage); + BrowserTestUtils.startLoadingURIString(browser, kTestXFOObjectURI); + await BrowserTestUtils.waitForCondition(() => xfoBlocked); + Services.console.unregisterListener(onXFOMessage); + }); +}); diff --git a/dom/security/test/general/bug1277803.html b/dom/security/test/general/bug1277803.html new file mode 100644 index 0000000000..c8033551a0 --- /dev/null +++ b/dom/security/test/general/bug1277803.html @@ -0,0 +1,11 @@ + + + + + + + +Nothing to see here... + + + diff --git a/dom/security/test/general/chrome.toml b/dom/security/test/general/chrome.toml new file mode 100644 index 0000000000..88feda944b --- /dev/null +++ b/dom/security/test/general/chrome.toml @@ -0,0 +1,15 @@ +[DEFAULT] +support-files = [ + "favicon_bug1277803.ico", + "bug1277803.html", +] + +["test_bug1277803.xhtml"] +skip-if = [ + "os == 'android'", + "verify", +] + +["test_innerhtml_sanitizer.html"] + +["test_innerhtml_sanitizer.xhtml"] diff --git a/dom/security/test/general/closeWindow.sjs b/dom/security/test/general/closeWindow.sjs new file mode 100644 index 0000000000..996db36f6f --- /dev/null +++ b/dom/security/test/general/closeWindow.sjs @@ -0,0 +1,24 @@ +const BODY = ` + `; + +function handleRequest(request, response) { + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + if (request.queryString.includes("unset")) { + response.setHeader("Set-Cookie", "test=wow", true); + } + + if (request.queryString.includes("none")) { + response.setHeader("Set-Cookie", "test2=wow2; samesite=none", true); + } + + if (request.queryString.includes("lax")) { + response.setHeader("Set-Cookie", "test3=wow3; samesite=lax", true); + } + + response.write(BODY); +} diff --git a/dom/security/test/general/favicon_bug1277803.ico b/dom/security/test/general/favicon_bug1277803.ico new file mode 100644 index 0000000000..d44438903b Binary files /dev/null and b/dom/security/test/general/favicon_bug1277803.ico differ diff --git a/dom/security/test/general/file_1767581.js b/dom/security/test/general/file_1767581.js new file mode 100644 index 0000000000..259435b1e4 --- /dev/null +++ b/dom/security/test/general/file_1767581.js @@ -0,0 +1 @@ +window.testResult = "fail-script-was-loaded"; diff --git a/dom/security/test/general/file_about_child.html b/dom/security/test/general/file_about_child.html new file mode 100644 index 0000000000..d83e0e4d41 --- /dev/null +++ b/dom/security/test/general/file_about_child.html @@ -0,0 +1,11 @@ + + + + + Test for Bug 1767581 + + + + Just an about page that loads in the privileged about process! + + \ No newline at end of file diff --git a/dom/security/test/general/file_assert_systemprincipal_documents.html b/dom/security/test/general/file_assert_systemprincipal_documents.html new file mode 100644 index 0000000000..2d7ff4d253 --- /dev/null +++ b/dom/security/test/general/file_assert_systemprincipal_documents.html @@ -0,0 +1,11 @@ + + + + Bug 1543579: Block web documents loading into system land + + +

This page loads documents from the SystemPrincipal (which should be blocked)

+ + + + diff --git a/dom/security/test/general/file_assert_systemprincipal_documents_iframe.html b/dom/security/test/general/file_assert_systemprincipal_documents_iframe.html new file mode 100644 index 0000000000..704625a1da --- /dev/null +++ b/dom/security/test/general/file_assert_systemprincipal_documents_iframe.html @@ -0,0 +1,9 @@ + + + + Bug 1543579: Block web documents loading into system land + + +

This is the iframe that should not load.

+ + diff --git a/dom/security/test/general/file_block_script_wrong_mime_server.sjs b/dom/security/test/general/file_block_script_wrong_mime_server.sjs new file mode 100644 index 0000000000..d034c797a4 --- /dev/null +++ b/dom/security/test/general/file_block_script_wrong_mime_server.sjs @@ -0,0 +1,37 @@ +// Custom *.sjs specifically for the needs of: +// Bug 1288361 - Block scripts with wrong MIME type + +"use strict"; + +const WORKER = ` + onmessage = function(event) { + postMessage("worker-loaded"); + };`; + +function handleRequest(request, response) { + const query = new URLSearchParams(request.queryString); + + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + // Set MIME type + response.setHeader("Content-Type", query.get("mime"), false); + + // Deliver response + switch (query.get("type")) { + case "script": + response.write(""); + break; + case "worker": + response.write(WORKER); + break; + case "worker-import": + response.write( + `importScripts("file_block_script_wrong_mime_server.sjs?type=script&mime=${query.get( + "mime" + )}");` + ); + response.write(WORKER); + break; + } +} diff --git a/dom/security/test/general/file_block_subresource_redir_to_data.sjs b/dom/security/test/general/file_block_subresource_redir_to_data.sjs new file mode 100644 index 0000000000..1e312bc810 --- /dev/null +++ b/dom/security/test/general/file_block_subresource_redir_to_data.sjs @@ -0,0 +1,33 @@ +"use strict"; + +let SCRIPT_DATA = "alert('this alert should be blocked');"; +let WORKER_DATA = + "onmessage = function(event) { postMessage('worker-loaded'); }"; + +function handleRequest(request, response) { + const query = request.queryString; + + response.setHeader("Cache-Control", "no-cache", false); + response.setStatusLine("1.1", 302, "Found"); + + if (query === "script" || query === "modulescript") { + response.setHeader( + "Location", + "data:text/javascript," + escape(SCRIPT_DATA), + false + ); + return; + } + + if (query === "worker") { + response.setHeader( + "Location", + "data:text/javascript," + escape(WORKER_DATA), + false + ); + return; + } + + // we should never get here; just in case return something unexpected + response.write("do'h"); +} diff --git a/dom/security/test/general/file_block_toplevel_data_navigation.html b/dom/security/test/general/file_block_toplevel_data_navigation.html new file mode 100644 index 0000000000..d6e083a247 --- /dev/null +++ b/dom/security/test/general/file_block_toplevel_data_navigation.html @@ -0,0 +1,16 @@ + + + + + Toplevel data navigation + + +test1: clicking data: URI tries to navigate window
+ +click me + + + diff --git a/dom/security/test/general/file_block_toplevel_data_navigation2.html b/dom/security/test/general/file_block_toplevel_data_navigation2.html new file mode 100644 index 0000000000..957189ce07 --- /dev/null +++ b/dom/security/test/general/file_block_toplevel_data_navigation2.html @@ -0,0 +1,17 @@ + + + + + Toplevel data navigation + + +test2: data: URI in iframe tries to window.open(data:, _blank);
+ + + + diff --git a/dom/security/test/general/file_block_toplevel_data_navigation3.html b/dom/security/test/general/file_block_toplevel_data_navigation3.html new file mode 100644 index 0000000000..3743a72034 --- /dev/null +++ b/dom/security/test/general/file_block_toplevel_data_navigation3.html @@ -0,0 +1,16 @@ + + + + + Toplevel data navigation + + +test3: performing data: URI navigation through win.loc.href
+ + + diff --git a/dom/security/test/general/file_block_toplevel_data_redirect.sjs b/dom/security/test/general/file_block_toplevel_data_redirect.sjs new file mode 100644 index 0000000000..c03ace5f23 --- /dev/null +++ b/dom/security/test/general/file_block_toplevel_data_redirect.sjs @@ -0,0 +1,13 @@ +// Custom *.sjs file specifically for the needs of Bug: +// Bug 1394554 - Block toplevel data: URI navigations after redirect + +var DATA_URI = + "toplevel data: URI navigations after redirect should be blocked"; + +function handleRequest(request, response) { + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + response.setStatusLine("1.1", 302, "Found"); + response.setHeader("Location", "data:text/html," + escape(DATA_URI), false); +} diff --git a/dom/security/test/general/file_cache_splitting_isloaded.sjs b/dom/security/test/general/file_cache_splitting_isloaded.sjs new file mode 100644 index 0000000000..a40b9674e5 --- /dev/null +++ b/dom/security/test/general/file_cache_splitting_isloaded.sjs @@ -0,0 +1,35 @@ +/* + Helper Server - + Send a Request with ?queryResult - response will be the + queryString of the next request. + +*/ +// small red image +const IMG_BYTES = atob( + "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12" + + "P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" +); + +function handleRequest(request, response) { + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + // save the object state of the initial request, which returns + // async once the server has processed the img request. + if (request.queryString.includes("wait")) { + response.processAsync(); + setObjectState("wait", response); + return; + } + + response.write(IMG_BYTES); + + // return the result + getObjectState("wait", function (queryResponse) { + if (!queryResponse) { + return; + } + queryResponse.write("1"); + queryResponse.finish(); + }); +} diff --git a/dom/security/test/general/file_cache_splitting_server.sjs b/dom/security/test/general/file_cache_splitting_server.sjs new file mode 100644 index 0000000000..da75986f74 --- /dev/null +++ b/dom/security/test/general/file_cache_splitting_server.sjs @@ -0,0 +1,27 @@ +function handleRequest(request, response) { + var receivedRequests = parseInt(getState("requests")); + if (isNaN(receivedRequests)) { + receivedRequests = 0; + } + if (request.queryString.includes("state")) { + response.write(receivedRequests); + return; + } + if (request.queryString.includes("flush")) { + setState("requests", "0"); + response.write("OK"); + return; + } + response.setHeader("Cache-Control", "max-age=999999"); // Force caching + response.setHeader("Content-Type", "text/css"); + receivedRequests = receivedRequests + 1; + setState("requests", "" + receivedRequests); + response.write(` + .test{ + color:red; + } + .test h1{ + font-size:200px; + } + `); +} diff --git a/dom/security/test/general/file_cache_splitting_window.html b/dom/security/test/general/file_cache_splitting_window.html new file mode 100644 index 0000000000..59a2ff2ca9 --- /dev/null +++ b/dom/security/test/general/file_cache_splitting_window.html @@ -0,0 +1,17 @@ + + + + + Document + + + +

HELLO WORLD!

+ + + + diff --git a/dom/security/test/general/file_contentpolicytype_targeted_link_iframe.sjs b/dom/security/test/general/file_contentpolicytype_targeted_link_iframe.sjs new file mode 100644 index 0000000000..9ee73ae3c4 --- /dev/null +++ b/dom/security/test/general/file_contentpolicytype_targeted_link_iframe.sjs @@ -0,0 +1,45 @@ +// custom *.sjs for Bug 1255240 + +const TEST_FRAME = ` + + + + + click me + + + + `; + +const INNER_FRAME = ` + + + + hello world! + + `; + +function handleRequest(request, response) { + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/html", false); + + var queryString = request.queryString; + + if (queryString === "testframe") { + response.write(TEST_FRAME); + return; + } + + if (queryString === "innerframe") { + response.write(INNER_FRAME); + return; + } + + // we should never get here, but just in case + // return something unexpected + response.write("do'h"); +} diff --git a/dom/security/test/general/file_data_download.html b/dom/security/test/general/file_data_download.html new file mode 100644 index 0000000000..4cc92fe8f5 --- /dev/null +++ b/dom/security/test/general/file_data_download.html @@ -0,0 +1,14 @@ + + + + Test download attribute for data: URI + + + download data + + + diff --git a/dom/security/test/general/file_data_text_csv.html b/dom/security/test/general/file_data_text_csv.html new file mode 100644 index 0000000000..a9ac369d16 --- /dev/null +++ b/dom/security/test/general/file_data_text_csv.html @@ -0,0 +1,14 @@ + + + + Test open data:text/csv + + + test text/csv + + + diff --git a/dom/security/test/general/file_empty.html b/dom/security/test/general/file_empty.html new file mode 100644 index 0000000000..865879c583 --- /dev/null +++ b/dom/security/test/general/file_empty.html @@ -0,0 +1 @@ + diff --git a/dom/security/test/general/file_framing_error_pages.sjs b/dom/security/test/general/file_framing_error_pages.sjs new file mode 100644 index 0000000000..fb62a34bdb --- /dev/null +++ b/dom/security/test/general/file_framing_error_pages.sjs @@ -0,0 +1,27 @@ +"use strict"; + +function handleRequest(request, response) { + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/html", false); + + let query = request.queryString; + if (query === "xfo") { + response.setHeader("x-frame-options", "deny", false); + response.write("xfo test loaded"); + return; + } + + if (query === "csp") { + response.setHeader( + "content-security-policy", + "frame-ancestors 'none'", + false + ); + response.write("csp test loaded"); + return; + } + + // we should never get here, but just in case + // return something unexpected + response.write("do'h"); +} diff --git a/dom/security/test/general/file_framing_error_pages_csp.html b/dom/security/test/general/file_framing_error_pages_csp.html new file mode 100644 index 0000000000..2764ed4aa6 --- /dev/null +++ b/dom/security/test/general/file_framing_error_pages_csp.html @@ -0,0 +1,7 @@ + + + +iframe should be blocked
+ + + diff --git a/dom/security/test/general/file_framing_error_pages_xfo.html b/dom/security/test/general/file_framing_error_pages_xfo.html new file mode 100644 index 0000000000..82dd1ee459 --- /dev/null +++ b/dom/security/test/general/file_framing_error_pages_xfo.html @@ -0,0 +1,7 @@ + + + +iframe should be blocked
+ + + diff --git a/dom/security/test/general/file_framing_xfo_embed.html b/dom/security/test/general/file_framing_xfo_embed.html new file mode 100644 index 0000000000..f5cc761b5b --- /dev/null +++ b/dom/security/test/general/file_framing_xfo_embed.html @@ -0,0 +1,7 @@ + + + + embed should be blocked
+ + + diff --git a/dom/security/test/general/file_framing_xfo_embed_object.sjs b/dom/security/test/general/file_framing_xfo_embed_object.sjs new file mode 100644 index 0000000000..56616b7930 --- /dev/null +++ b/dom/security/test/general/file_framing_xfo_embed_object.sjs @@ -0,0 +1,7 @@ +"use strict"; + +function handleRequest(request, response) { + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("x-frame-options", "deny", false); + response.write("doc with x-frame-options: deny"); +} diff --git a/dom/security/test/general/file_framing_xfo_object.html b/dom/security/test/general/file_framing_xfo_object.html new file mode 100644 index 0000000000..c8480a2c42 --- /dev/null +++ b/dom/security/test/general/file_framing_xfo_object.html @@ -0,0 +1,7 @@ + + + + object should be blocked
+ + + diff --git a/dom/security/test/general/file_gpc_server.sjs b/dom/security/test/general/file_gpc_server.sjs new file mode 100644 index 0000000000..d0b14215b4 --- /dev/null +++ b/dom/security/test/general/file_gpc_server.sjs @@ -0,0 +1,14 @@ +"use strict"; + +function handleRequest(request, response) { + response.setHeader("Content-Type", "text/html", false); + response.setHeader("Cache-Control", "no-cache", false); + + var gpc = request.hasHeader("Sec-GPC") ? request.getHeader("Sec-GPC") : ""; + + if (gpc === "1") { + response.write("true"); + } else { + response.write("false"); + } +} diff --git a/dom/security/test/general/file_loads_nonscript.html b/dom/security/test/general/file_loads_nonscript.html new file mode 100644 index 0000000000..f7692b8066 --- /dev/null +++ b/dom/security/test/general/file_loads_nonscript.html @@ -0,0 +1,49 @@ + + + + File that loads a non-script file-extension as script + + + + diff --git a/dom/security/test/general/file_meta_referrer_in_head.html b/dom/security/test/general/file_meta_referrer_in_head.html new file mode 100644 index 0000000000..9c4c4cd695 --- /dev/null +++ b/dom/security/test/general/file_meta_referrer_in_head.html @@ -0,0 +1,13 @@ + + + + + +Bug 1704473 - Remove head requirement for meta name=referrer + + + + + diff --git a/dom/security/test/general/file_meta_referrer_notin_head.html b/dom/security/test/general/file_meta_referrer_notin_head.html new file mode 100644 index 0000000000..55bd38e4c5 --- /dev/null +++ b/dom/security/test/general/file_meta_referrer_notin_head.html @@ -0,0 +1,14 @@ + + + + +Bug 1704473 - Remove head requirement for meta name=referrer + + + + + + + diff --git a/dom/security/test/general/file_nonscript b/dom/security/test/general/file_nonscript new file mode 100644 index 0000000000..c339e45d5d --- /dev/null +++ b/dom/security/test/general/file_nonscript @@ -0,0 +1 @@ +window.counter++; diff --git a/dom/security/test/general/file_nonscript.html b/dom/security/test/general/file_nonscript.html new file mode 100644 index 0000000000..c339e45d5d --- /dev/null +++ b/dom/security/test/general/file_nonscript.html @@ -0,0 +1 @@ +window.counter++; diff --git a/dom/security/test/general/file_nonscript.json b/dom/security/test/general/file_nonscript.json new file mode 100644 index 0000000000..c339e45d5d --- /dev/null +++ b/dom/security/test/general/file_nonscript.json @@ -0,0 +1 @@ +window.counter++; diff --git a/dom/security/test/general/file_nonscript.txt b/dom/security/test/general/file_nonscript.txt new file mode 100644 index 0000000000..c339e45d5d --- /dev/null +++ b/dom/security/test/general/file_nonscript.txt @@ -0,0 +1 @@ +window.counter++; diff --git a/dom/security/test/general/file_nonscript.xyz b/dom/security/test/general/file_nonscript.xyz new file mode 100644 index 0000000000..c339e45d5d --- /dev/null +++ b/dom/security/test/general/file_nonscript.xyz @@ -0,0 +1 @@ +window.counter++; diff --git a/dom/security/test/general/file_nosniff_navigation.sjs b/dom/security/test/general/file_nosniff_navigation.sjs new file mode 100644 index 0000000000..d332d860fd --- /dev/null +++ b/dom/security/test/general/file_nosniff_navigation.sjs @@ -0,0 +1,39 @@ +// Custom *.sjs file specifically for the needs of Bug 1286861 + +// small red image +const IMG = atob( + "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12" + + "P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" +); + +// https://stackoverflow.com/questions/17279712/what-is-the-smallest-possible-valid-pdf +const PDF = `%PDF-1.0 +1 0 obj<>endobj 2 0 obj<>endobj 3 0 obj<>endobj +trailer<>`; + +function getSniffableContent(type) { + switch (type) { + case "xml": + return ``; + case "html": + return ` Test test `; + case "css": + return `*{ color: pink !important; }`; + case "json": + return `{ 'test':'yes' }`; + case "img": + return IMG; + case "pdf": + return PDF; + } + return "Basic UTF-8 Text"; +} + +function handleRequest(request, response) { + let query = new URLSearchParams(request.queryString); + + // avoid confusing cache behaviors (XXXX no sure what this means?) + response.setHeader("X-Content-Type-Options", "nosniff"); // Disable Sniffing + response.setHeader("Content-Type", query.get("mime")); + response.write(getSniffableContent(query.get("content"))); +} diff --git a/dom/security/test/general/file_nosniff_testserver.sjs b/dom/security/test/general/file_nosniff_testserver.sjs new file mode 100644 index 0000000000..d3e52979a4 --- /dev/null +++ b/dom/security/test/general/file_nosniff_testserver.sjs @@ -0,0 +1,60 @@ +"use strict"; + +const SCRIPT = "var foo = 24;"; +const CSS = "body { background-color: green; }"; + +// small red image +const IMG = atob( + "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12" + + "P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" +); + +function handleRequest(request, response) { + const query = new URLSearchParams(request.queryString); + + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + // set the nosniff header + response.setHeader("X-Content-Type-Options", " NoSniFF , foo ", false); + + if (query.has("cssCorrectType")) { + response.setHeader("Content-Type", "teXt/cSs", false); + response.write(CSS); + return; + } + + if (query.has("cssWrongType")) { + response.setHeader("Content-Type", "text/html", false); + response.write(CSS); + return; + } + + if (query.has("scriptCorrectType")) { + response.setHeader("Content-Type", "appLIcation/jAvaScriPt;blah", false); + response.write(SCRIPT); + return; + } + + if (query.has("scriptWrongType")) { + response.setHeader("Content-Type", "text/html", false); + response.write(SCRIPT); + return; + } + + if (query.has("imgCorrectType")) { + response.setHeader("Content-Type", "iMaGe/pnG;blah", false); + response.write(IMG); + return; + } + + if (query.has("imgWrongType")) { + response.setHeader("Content-Type", "text/html", false); + response.write(IMG); + return; + } + + // we should never get here, but just in case + response.setHeader("Content-Type", "text/html", false); + response.write("do'h"); +} diff --git a/dom/security/test/general/file_same_site_cookies_about.sjs b/dom/security/test/general/file_same_site_cookies_about.sjs new file mode 100644 index 0000000000..421eb999be --- /dev/null +++ b/dom/security/test/general/file_same_site_cookies_about.sjs @@ -0,0 +1,99 @@ +// Custom *.sjs file specifically for the needs of Bug 1454721 + +// small red image +const IMG_BYTES = atob( + "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12" + + "P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" +); + +const IFRAME_INC = ``; + +function handleRequest(request, response) { + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + // using startsWith and discard the math random + if (request.queryString.startsWith("setSameSiteCookie")) { + response.setHeader( + "Set-Cookie", + "myKey=mySameSiteAboutCookie; samesite=strict", + true + ); + response.setHeader("Content-Type", "image/png"); + response.write(IMG_BYTES); + return; + } + + // navigation tests + if (request.queryString.includes("loadsrcdocframeNav")) { + let FRAME = ` + `; + response.write(FRAME); + return; + } + + if (request.queryString.includes("loadblankframeNav")) { + let FRAME = ` + `; + response.write(FRAME); + return; + } + + // inclusion tets + if (request.queryString.includes("loadsrcdocframeInc")) { + response.write(''); + return; + } + + if (request.queryString.includes("loadblankframeInc")) { + let FRAME = + ` + + + + + `); + } + + if (request.queryString.includes("inclusion")) { + const cookies = request.hasHeader("Cookie") + ? request.getHeader("Cookie") + : ""; + response.write(` + + + + + + + `); + } + + // we should never get here, but just in case return something unexpected + response.write("D'oh"); +} diff --git a/dom/security/test/general/file_same_site_cookies_blob_iframe_inclusion.html b/dom/security/test/general/file_same_site_cookies_blob_iframe_inclusion.html new file mode 100644 index 0000000000..b3456f0b90 --- /dev/null +++ b/dom/security/test/general/file_same_site_cookies_blob_iframe_inclusion.html @@ -0,0 +1,34 @@ + + + + + + diff --git a/dom/security/test/general/file_same_site_cookies_blob_iframe_navigation.html b/dom/security/test/general/file_same_site_cookies_blob_iframe_navigation.html new file mode 100644 index 0000000000..815c6a6bfc --- /dev/null +++ b/dom/security/test/general/file_same_site_cookies_blob_iframe_navigation.html @@ -0,0 +1,30 @@ + + + + + + diff --git a/dom/security/test/general/file_same_site_cookies_bug1748693.sjs b/dom/security/test/general/file_same_site_cookies_bug1748693.sjs new file mode 100644 index 0000000000..6890bafa17 --- /dev/null +++ b/dom/security/test/general/file_same_site_cookies_bug1748693.sjs @@ -0,0 +1,31 @@ +const MESSAGE_PAGE = function (msg) { + return ` + + + +

${msg}

+ + +`; +}; + +function handleRequest(request, response) { + response.setHeader("Cache-Control", "no-store"); + response.setHeader("Content-Type", "text/html"); + + if (request.queryString.includes("setcookies")) { + response.setHeader( + "Set-Cookie", + "auth_secure=foo; SameSite=None; HttpOnly; Secure", + true + ); + response.setHeader("Set-Cookie", "auth=foo; HttpOnly;", true); + response.write(MESSAGE_PAGE(request.queryString)); + return; + } + + const cookies = request.hasHeader("Cookie") + ? request.getHeader("Cookie") + : ""; + response.write(MESSAGE_PAGE(cookies)); +} diff --git a/dom/security/test/general/file_same_site_cookies_cross_origin_context.sjs b/dom/security/test/general/file_same_site_cookies_cross_origin_context.sjs new file mode 100644 index 0000000000..9103941653 --- /dev/null +++ b/dom/security/test/general/file_same_site_cookies_cross_origin_context.sjs @@ -0,0 +1,54 @@ +// Custom *.sjs file specifically for the needs of Bug 1452496 + +// small red image +const IMG_BYTES = atob( + "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12" + + "P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" +); + +const FRAME = ` + + + + Bug 1452496 - Do not allow same-site cookies in cross site context + + + + + `; + +function handleRequest(request, response) { + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + if (request.queryString.includes("setSameSiteCookie")) { + response.setHeader( + "Set-Cookie", + "myKey=strictSameSiteCookie; samesite=strict", + true + ); + response.setHeader("Content-Type", "image/png"); + response.write(IMG_BYTES); + return; + } + + if (request.queryString.includes("setRegularCookie")) { + response.setHeader("Set-Cookie", "myKey=regularCookie;", true); + response.setHeader("Content-Type", "image/png"); + response.write(IMG_BYTES); + return; + } + + if (request.queryString.includes("loadFrame")) { + response.write(FRAME); + return; + } + + // we should never get here, but just in case return something unexpected + response.write("D'oh"); +} diff --git a/dom/security/test/general/file_same_site_cookies_from_script.sjs b/dom/security/test/general/file_same_site_cookies_from_script.sjs new file mode 100644 index 0000000000..0df217cf45 --- /dev/null +++ b/dom/security/test/general/file_same_site_cookies_from_script.sjs @@ -0,0 +1,48 @@ +// Custom *.sjs file specifically for the needs of Bug 1452496 + +const SET_COOKIE_FRAME = ` + + + + Bug 1452496 - Do not allow same-site cookies in cross site context + + + + + `; + +const GET_COOKIE_FRAME = ` + + + + Bug 1452496 - Do not allow same-site cookies in cross site context + + + + + `; + +function handleRequest(request, response) { + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + if (request.queryString.includes("setSameSiteCookieUsingInlineScript")) { + response.write(SET_COOKIE_FRAME); + return; + } + + if (request.queryString.includes("getCookieFrame")) { + response.write(GET_COOKIE_FRAME); + return; + } + + // we should never get here, but just in case return something unexpected + response.write("D'oh"); +} diff --git a/dom/security/test/general/file_same_site_cookies_iframe.sjs b/dom/security/test/general/file_same_site_cookies_iframe.sjs new file mode 100644 index 0000000000..7b511257c3 --- /dev/null +++ b/dom/security/test/general/file_same_site_cookies_iframe.sjs @@ -0,0 +1,99 @@ +// Custom *.sjs file specifically for the needs of Bug 1454027 + +// small red image +const IMG_BYTES = atob( + "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12" + + "P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" +); + +const NESTED_IFRAME_NAVIGATION = ` + + + + + + + `); +} diff --git a/dom/security/test/general/file_same_site_cookies_redirect.sjs b/dom/security/test/general/file_same_site_cookies_redirect.sjs new file mode 100644 index 0000000000..f7451fb504 --- /dev/null +++ b/dom/security/test/general/file_same_site_cookies_redirect.sjs @@ -0,0 +1,103 @@ +// Custom *.sjs file specifically for the needs of Bug 1453814 + +// small red image +const IMG_BYTES = atob( + "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12" + + "P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" +); + +const FRAME = ` + + + + Bug 1453814 - Do not allow same-site cookies for cross origin redirect + + + + + `; + +const SAME_ORIGIN = "http://mochi.test:8888/"; +const CROSS_ORIGIN = "http://example.com/"; +const PATH = + "tests/dom/security/test/general/file_same_site_cookies_redirect.sjs"; + +const FRAME_META_REFRESH_SAME = + ` + + + `; + +const FRAME_META_REFRESH_CROSS = + ` + + + `; + +function handleRequest(request, response) { + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + if (request.queryString === "setSameSiteCookie") { + response.setHeader( + "Set-Cookie", + "myKey=strictSameSiteCookie; samesite=strict", + true + ); + response.setHeader("Content-Type", "image/png"); + response.write(IMG_BYTES); + return; + } + + if (request.queryString === "sameToSameRedirect") { + let URL = SAME_ORIGIN + PATH + "?loadFrame"; + response.setStatusLine("1.1", 302, "Found"); + response.setHeader("Location", URL, false); + return; + } + + if (request.queryString === "sameToCrossRedirect") { + let URL = CROSS_ORIGIN + PATH + "?loadFrame"; + response.setStatusLine("1.1", 302, "Found"); + response.setHeader("Location", URL, false); + return; + } + + if (request.queryString === "crossToSameRedirect") { + let URL = SAME_ORIGIN + PATH + "?loadFrame"; + response.setStatusLine("1.1", 302, "Found"); + response.setHeader("Location", URL, false); + return; + } + + if (request.queryString === "sameToCrossRedirectMeta") { + response.write(FRAME_META_REFRESH_CROSS); + return; + } + + if (request.queryString === "crossToSameRedirectMeta") { + response.write(FRAME_META_REFRESH_SAME); + return; + } + + if (request.queryString === "loadFrame") { + response.write(FRAME); + return; + } + + // we should never get here, but just in case return something unexpected + response.write("D'oh"); +} diff --git a/dom/security/test/general/file_same_site_cookies_subrequest.sjs b/dom/security/test/general/file_same_site_cookies_subrequest.sjs new file mode 100644 index 0000000000..fdc81344ef --- /dev/null +++ b/dom/security/test/general/file_same_site_cookies_subrequest.sjs @@ -0,0 +1,82 @@ +// Custom *.sjs file specifically for the needs of Bug 1286861 + +// small red image +const IMG_BYTES = atob( + "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12" + + "P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" +); + +const FRAME = ` + + + + Bug 1286861 - Add support for same site cookies + + + + + `; + +function handleRequest(request, response) { + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + if (request.queryString.includes("setStrictSameSiteCookie")) { + response.setHeader( + "Set-Cookie", + "myKey=strictSameSiteCookie; samesite=strict", + true + ); + response.setHeader("Content-Type", "image/png"); + response.write(IMG_BYTES); + return; + } + + if (request.queryString.includes("setLaxSameSiteCookie")) { + response.setHeader( + "Set-Cookie", + "myKey=laxSameSiteCookie; samesite=lax", + true + ); + response.setHeader("Content-Type", "image/png"); + response.write(IMG_BYTES); + return; + } + + // save the object state of the initial request, which returns + // async once the server has processed the img request. + if (request.queryString.includes("queryresult")) { + response.processAsync(); + setObjectState("queryResult", response); + return; + } + + if (request.queryString.includes("loadFrame")) { + response.write(FRAME); + return; + } + + if (request.queryString.includes("checkCookie")) { + var cookie = "unitialized"; + if (request.hasHeader("Cookie")) { + cookie = request.getHeader("Cookie"); + } else { + cookie = "myKey=noCookie"; + } + response.setHeader("Content-Type", "image/png"); + response.write(IMG_BYTES); + + // return the result + getObjectState("queryResult", function (queryResponse) { + if (!queryResponse) { + return; + } + queryResponse.write(cookie); + queryResponse.finish(); + }); + return; + } + + // we should never get here, but just in case return something unexpected + response.write("D'oh"); +} diff --git a/dom/security/test/general/file_same_site_cookies_toplevel_nav.sjs b/dom/security/test/general/file_same_site_cookies_toplevel_nav.sjs new file mode 100644 index 0000000000..45b515a28b --- /dev/null +++ b/dom/security/test/general/file_same_site_cookies_toplevel_nav.sjs @@ -0,0 +1,96 @@ +// Custom *.sjs file specifically for the needs of Bug 1286861 + +// small red image +const IMG_BYTES = atob( + "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12" + + "P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" +); + +const FRAME = ` + + + + Bug 1286861 - Add support for same site cookies + + + + + `; + +const WIN = ` + + + + just a dummy window + + + `; + +function handleRequest(request, response) { + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + if (request.queryString.includes("setStrictSameSiteCookie")) { + response.setHeader( + "Set-Cookie", + "myKey=strictSameSiteCookie; samesite=strict", + true + ); + response.setHeader("Content-Type", "image/png"); + response.write(IMG_BYTES); + return; + } + + if (request.queryString.includes("setLaxSameSiteCookie")) { + response.setHeader( + "Set-Cookie", + "myKey=laxSameSiteCookie; samesite=lax", + true + ); + response.setHeader("Content-Type", "image/png"); + response.write(IMG_BYTES); + return; + } + + // save the object state of the initial request, which returns + // async once the server has processed the img request. + if (request.queryString.includes("queryresult")) { + response.processAsync(); + setObjectState("queryResult", response); + return; + } + + if (request.queryString.includes("loadFrame")) { + response.write(FRAME); + return; + } + + if (request.queryString.includes("loadWin")) { + var cookie = "unitialized"; + if (request.hasHeader("Cookie")) { + cookie = request.getHeader("Cookie"); + } else { + cookie = "myKey=noCookie"; + } + response.write(WIN); + + // return the result + getObjectState("queryResult", function (queryResponse) { + if (!queryResponse) { + return; + } + queryResponse.write(cookie); + queryResponse.finish(); + }); + return; + } + + // we should never get here, but just in case return something unexpected + response.write("D'oh"); +} diff --git a/dom/security/test/general/file_same_site_cookies_toplevel_set_cookie.sjs b/dom/security/test/general/file_same_site_cookies_toplevel_set_cookie.sjs new file mode 100644 index 0000000000..34dfe40e23 --- /dev/null +++ b/dom/security/test/general/file_same_site_cookies_toplevel_set_cookie.sjs @@ -0,0 +1,68 @@ +// Custom *.sjs file specifically for the needs of Bug 1454242 + +const WIN = ` + + + + + `; + +const DUMMY_WIN = ` + + + just a dummy window that sets a same-site=lax cookie + + + `; + +const FRAME = ` + + + + + `; + +const SAME_ORIGIN = "http://mochi.test:8888/"; +const CROSS_ORIGIN = "http://example.com/"; +const PATH = + "tests/dom/security/test/general/file_same_site_cookies_redirect.sjs"; + +function handleRequest(request, response) { + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + if (request.queryString === "loadWin") { + response.write(WIN); + return; + } + + if (request.queryString === "loadWinAndSetCookie") { + response.setHeader( + "Set-Cookie", + "myKey=laxSameSiteCookie; samesite=lax", + true + ); + response.write(DUMMY_WIN); + return; + } + + if (request.queryString === "checkCookie") { + response.write(FRAME); + return; + } + + // we should never get here, but just in case return something unexpected + response.write("D'oh"); +} diff --git a/dom/security/test/general/file_script.js b/dom/security/test/general/file_script.js new file mode 100644 index 0000000000..c339e45d5d --- /dev/null +++ b/dom/security/test/general/file_script.js @@ -0,0 +1 @@ +window.counter++; diff --git a/dom/security/test/general/file_toplevel_data_meta_redirect.html b/dom/security/test/general/file_toplevel_data_meta_redirect.html new file mode 100644 index 0000000000..e94a61ed48 --- /dev/null +++ b/dom/security/test/general/file_toplevel_data_meta_redirect.html @@ -0,0 +1,10 @@ + + + + + + +Meta Redirect to data: URI + + diff --git a/dom/security/test/general/file_toplevel_data_navigations.sjs b/dom/security/test/general/file_toplevel_data_navigations.sjs new file mode 100644 index 0000000000..57c4b527dd --- /dev/null +++ b/dom/security/test/general/file_toplevel_data_navigations.sjs @@ -0,0 +1,13 @@ +// Custom *.sjs file specifically for the needs of Bug: +// Bug 1394554 - Block toplevel data: URI navigations after redirect + +var DATA_URI = + "data:text/html,toplevel data: URI navigations after redirect should be blocked"; + +function handleRequest(request, response) { + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + response.setStatusLine("1.1", 302, "Found"); + response.setHeader("Location", DATA_URI, false); +} diff --git a/dom/security/test/general/file_view_bg_image_data_navigation.html b/dom/security/test/general/file_view_bg_image_data_navigation.html new file mode 100644 index 0000000000..d9aa6ca8b6 --- /dev/null +++ b/dom/security/test/general/file_view_bg_image_data_navigation.html @@ -0,0 +1,16 @@ + + + + + Bug 1658244: Test navigation for right-click view-bg-image on data:image/svg + + + + This page has an inline SVG image as a background. + + diff --git a/dom/security/test/general/file_view_image_data_navigation.html b/dom/security/test/general/file_view_image_data_navigation.html new file mode 100644 index 0000000000..a3f9acfb4d --- /dev/null +++ b/dom/security/test/general/file_view_image_data_navigation.html @@ -0,0 +1,12 @@ + + + + + Bug 1407891: Test navigation for right-click view-image on data:image/svg + + + + + + + diff --git a/dom/security/test/general/file_xfo_error_page.sjs b/dom/security/test/general/file_xfo_error_page.sjs new file mode 100644 index 0000000000..b1fa33cbd4 --- /dev/null +++ b/dom/security/test/general/file_xfo_error_page.sjs @@ -0,0 +1,8 @@ +"use strict"; + +function handleRequest(request, response) { + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/html", false); + response.setHeader("x-frame-options", "deny", false); + response.write("xfo test loaded"); +} diff --git a/dom/security/test/general/mochitest.toml b/dom/security/test/general/mochitest.toml new file mode 100644 index 0000000000..c46b5ecf57 --- /dev/null +++ b/dom/security/test/general/mochitest.toml @@ -0,0 +1,148 @@ +[DEFAULT] +support-files = [ + "file_contentpolicytype_targeted_link_iframe.sjs", + "file_nosniff_testserver.sjs", + "file_nosniff_navigation.sjs", + "file_block_script_wrong_mime_server.sjs", + "file_block_toplevel_data_navigation.html", + "file_block_toplevel_data_navigation2.html", + "file_block_toplevel_data_navigation3.html", + "file_block_toplevel_data_redirect.sjs", + "file_block_subresource_redir_to_data.sjs", + "file_same_site_cookies_subrequest.sjs", + "file_same_site_cookies_toplevel_nav.sjs", + "file_same_site_cookies_cross_origin_context.sjs", + "file_same_site_cookies_from_script.sjs", + "file_same_site_cookies_redirect.sjs", + "file_same_site_cookies_toplevel_set_cookie.sjs", + "file_same_site_cookies_blob_iframe_navigation.html", + "file_same_site_cookies_blob_iframe_inclusion.html", + "file_same_site_cookies_iframe.sjs", + "file_same_site_cookies_about.sjs", + "file_cache_splitting_server.sjs", + "file_cache_splitting_isloaded.sjs", + "file_cache_splitting_window.html", + "window_nosniff_navigation.html", +] + +["test_allow_opening_data_json.html"] + +["test_allow_opening_data_pdf.html"] +skip-if = ["os == 'android'"] # no pdf reader on Android + +["test_assert_about_page_no_csp.html"] +skip-if = ["!debug"] + +["test_block_script_wrong_mime.html"] + +["test_block_subresource_redir_to_data.html"] + +["test_block_toplevel_data_img_navigation.html"] + +["test_block_toplevel_data_navigation.html"] + +["test_bug1450853.html"] +skip-if = [ + "http3", + "http2", +] + +["test_bug1660452_http.html"] +skip-if = [ + "http3", + "http2", +] + +["test_bug1660452_https.html"] +scheme = "https" + +["test_cache_split.html"] +skip-if = [ + "http3", + "http2", +] + +["test_contentpolicytype_targeted_link_iframe.html"] +skip-if = [ + "http3", + "http2", +] + +["test_gpc.html"] +support-files = ["file_gpc_server.sjs"] + +["test_meta_referrer.html"] +support-files = [ + "file_meta_referrer_in_head.html", + "file_meta_referrer_notin_head.html", +] + +["test_nosniff.html"] + +["test_nosniff_navigation.html"] + +["test_same_site_cookies_about.html"] +fail-if = ["xorigin"] +skip-if = [ + "http3", + "http2", +] + +["test_same_site_cookies_cross_origin_context.html"] +skip-if = [ + "http3", + "http2", +] + +["test_same_site_cookies_from_script.html"] +fail-if = ["xorigin"] +skip-if = [ + "http3", + "http2", +] + +["test_same_site_cookies_iframe.html"] +fail-if = ["xorigin"] +skip-if = [ + "http3", + "http2", +] + +["test_same_site_cookies_laxByDefault.html"] +skip-if = ["debug"] +support-files = ["closeWindow.sjs"] + +["test_same_site_cookies_redirect.html"] +fail-if = ["xorigin"] +skip-if = [ + "http3", + "http2", +] + +["test_same_site_cookies_subrequest.html"] +fail-if = ["xorigin"] # Cookies set incorrectly +skip-if = [ + "http3", + "http2", +] + +["test_same_site_cookies_toplevel_nav.html"] +fail-if = ["xorigin"] +skip-if = [ + "http3", + "http2", +] + +["test_same_site_cookies_toplevel_set_cookie.html"] +fail-if = ["xorigin"] # Cookies not set +skip-if = [ + "http3", + "http2", +] + +["test_xfo_error_page.html"] +support-files = ["file_xfo_error_page.sjs"] +skip-if = [ + "http3", + "http2", +] diff --git a/dom/security/test/general/test_allow_opening_data_json.html b/dom/security/test/general/test_allow_opening_data_json.html new file mode 100644 index 0000000000..4b37931e1f --- /dev/null +++ b/dom/security/test/general/test_allow_opening_data_json.html @@ -0,0 +1,39 @@ + + + + + Bug 1403814: Allow toplevel data URI navigation data:application/json + + + + + + + diff --git a/dom/security/test/general/test_allow_opening_data_pdf.html b/dom/security/test/general/test_allow_opening_data_pdf.html new file mode 100644 index 0000000000..007b3e8801 --- /dev/null +++ b/dom/security/test/general/test_allow_opening_data_pdf.html @@ -0,0 +1,41 @@ + + + + + Bug 1398692: Allow toplevel navigation to a data:application/pdf + + + + + + + diff --git a/dom/security/test/general/test_assert_about_page_no_csp.html b/dom/security/test/general/test_assert_about_page_no_csp.html new file mode 100644 index 0000000000..06be4ce460 --- /dev/null +++ b/dom/security/test/general/test_assert_about_page_no_csp.html @@ -0,0 +1,30 @@ + + + + Bug 1490977: Test Assertion if content privileged about: page has no CSP + + + + + + + + + diff --git a/dom/security/test/general/test_block_script_wrong_mime.html b/dom/security/test/general/test_block_script_wrong_mime.html new file mode 100644 index 0000000000..93a4b9d220 --- /dev/null +++ b/dom/security/test/general/test_block_script_wrong_mime.html @@ -0,0 +1,92 @@ + + + + Bug 1288361 - Block scripts with incorrect MIME type + + + + + + + + + diff --git a/dom/security/test/general/test_block_subresource_redir_to_data.html b/dom/security/test/general/test_block_subresource_redir_to_data.html new file mode 100644 index 0000000000..21a85515ec --- /dev/null +++ b/dom/security/test/general/test_block_subresource_redir_to_data.html @@ -0,0 +1,66 @@ + + + + Bug 1428793: Block insecure redirects to data: URIs + + + + + + + + + + + diff --git a/dom/security/test/general/test_block_toplevel_data_img_navigation.html b/dom/security/test/general/test_block_toplevel_data_img_navigation.html new file mode 100644 index 0000000000..07e46b1f2f --- /dev/null +++ b/dom/security/test/general/test_block_toplevel_data_img_navigation.html @@ -0,0 +1,53 @@ + + + + + Bug 1396798: Do not block toplevel data: navigation to image (except svgs) + + + + + + + diff --git a/dom/security/test/general/test_block_toplevel_data_navigation.html b/dom/security/test/general/test_block_toplevel_data_navigation.html new file mode 100644 index 0000000000..bbadacb218 --- /dev/null +++ b/dom/security/test/general/test_block_toplevel_data_navigation.html @@ -0,0 +1,134 @@ + + + + + Bug 1331351 - Block top level window data: URI navigations + + + + + + + + diff --git a/dom/security/test/general/test_bug1277803.xhtml b/dom/security/test/general/test_bug1277803.xhtml new file mode 100644 index 0000000000..30cc82310b --- /dev/null +++ b/dom/security/test/general/test_bug1277803.xhtml @@ -0,0 +1,65 @@ + + + + + + + + + + diff --git a/dom/security/test/general/test_bug1450853.html b/dom/security/test/general/test_bug1450853.html new file mode 100644 index 0000000000..e6b61ecce0 --- /dev/null +++ b/dom/security/test/general/test_bug1450853.html @@ -0,0 +1,91 @@ + + + + + +Test for Cross-origin resouce status leak via MediaError + + + + + + + + + + + Mozilla Bug 1450853 + + + diff --git a/dom/security/test/general/test_bug1660452_http.html b/dom/security/test/general/test_bug1660452_http.html new file mode 100644 index 0000000000..3a6512da21 --- /dev/null +++ b/dom/security/test/general/test_bug1660452_http.html @@ -0,0 +1,39 @@ + + + +Bug 1660452: NullPrincipals need to know whether they were spun off of a Secure Context + + + + + + + + diff --git a/dom/security/test/general/test_bug1660452_https.html b/dom/security/test/general/test_bug1660452_https.html new file mode 100644 index 0000000000..1aed356a21 --- /dev/null +++ b/dom/security/test/general/test_bug1660452_https.html @@ -0,0 +1,39 @@ + + + +Bug 1660452: NullPrincipals need to know whether they were spun off of a Secure Context + + + + + + + + diff --git a/dom/security/test/general/test_cache_split.html b/dom/security/test/general/test_cache_split.html new file mode 100644 index 0000000000..f0fc056bce --- /dev/null +++ b/dom/security/test/general/test_cache_split.html @@ -0,0 +1,153 @@ + + + + + + Bug 1454721 - Add same-site cookie test for about:blank and about:srcdoc + + + + + + + + + + + diff --git a/dom/security/test/general/test_contentpolicytype_targeted_link_iframe.html b/dom/security/test/general/test_contentpolicytype_targeted_link_iframe.html new file mode 100644 index 0000000000..24ec5dbdd9 --- /dev/null +++ b/dom/security/test/general/test_contentpolicytype_targeted_link_iframe.html @@ -0,0 +1,103 @@ + + + + + Bug 1255240 - Test content policy types within content policies for targeted links in iframes + + + + + + + + + + diff --git a/dom/security/test/general/test_gpc.html b/dom/security/test/general/test_gpc.html new file mode 100644 index 0000000000..506629554d --- /dev/null +++ b/dom/security/test/general/test_gpc.html @@ -0,0 +1,51 @@ + + + + Test for Global Privacy Control headers + + + + + + + diff --git a/dom/security/test/general/test_innerhtml_sanitizer.html b/dom/security/test/general/test_innerhtml_sanitizer.html new file mode 100644 index 0000000000..4a4e4efed1 --- /dev/null +++ b/dom/security/test/general/test_innerhtml_sanitizer.html @@ -0,0 +1,74 @@ + + + + + Test for Bug 1667113 + + + + +Mozilla Bug 1667113 +
+ + + diff --git a/dom/security/test/general/test_innerhtml_sanitizer.xhtml b/dom/security/test/general/test_innerhtml_sanitizer.xhtml new file mode 100644 index 0000000000..4d938bc23b --- /dev/null +++ b/dom/security/test/general/test_innerhtml_sanitizer.xhtml @@ -0,0 +1,73 @@ + + + + Test for Bug 1667113 + + + + +Mozilla Bug 1667113 +
+ + + diff --git a/dom/security/test/general/test_meta_referrer.html b/dom/security/test/general/test_meta_referrer.html new file mode 100644 index 0000000000..f5e8b649f4 --- /dev/null +++ b/dom/security/test/general/test_meta_referrer.html @@ -0,0 +1,55 @@ + + + + Bug 1704473 - Remove head requirement for meta name=referrer + + + + + + + + + + + diff --git a/dom/security/test/general/test_nosniff.html b/dom/security/test/general/test_nosniff.html new file mode 100644 index 0000000000..a22386aea0 --- /dev/null +++ b/dom/security/test/general/test_nosniff.html @@ -0,0 +1,88 @@ + + + + Bug 471020 - Add X-Content-Type-Options: nosniff support to Firefox + + + + + + + + + + + + + + + + + diff --git a/dom/security/test/general/test_nosniff_navigation.html b/dom/security/test/general/test_nosniff_navigation.html new file mode 100644 index 0000000000..6710f4f5b9 --- /dev/null +++ b/dom/security/test/general/test_nosniff_navigation.html @@ -0,0 +1,35 @@ + + + + + Bug 1428473 Support X-Content-Type-Options: nosniff when navigating + + + + + + + + + + + + + + diff --git a/dom/security/test/general/test_same_site_cookies_about.html b/dom/security/test/general/test_same_site_cookies_about.html new file mode 100644 index 0000000000..faf2caab9a --- /dev/null +++ b/dom/security/test/general/test_same_site_cookies_about.html @@ -0,0 +1,116 @@ + + + + Bug 1454721 - Add same-site cookie test for about:blank and about:srcdoc + + + + + + + + + + diff --git a/dom/security/test/general/test_same_site_cookies_cross_origin_context.html b/dom/security/test/general/test_same_site_cookies_cross_origin_context.html new file mode 100644 index 0000000000..9294a3d030 --- /dev/null +++ b/dom/security/test/general/test_same_site_cookies_cross_origin_context.html @@ -0,0 +1,93 @@ + + + + Bug 1452496 - Do not allow same-site cookies in cross site context + + + + + + + + + + diff --git a/dom/security/test/general/test_same_site_cookies_from_script.html b/dom/security/test/general/test_same_site_cookies_from_script.html new file mode 100644 index 0000000000..74c38b6249 --- /dev/null +++ b/dom/security/test/general/test_same_site_cookies_from_script.html @@ -0,0 +1,86 @@ + + + + Bug 1452496 - Do not allow same-site cookies in cross site context + + + + + + + + + + + diff --git a/dom/security/test/general/test_same_site_cookies_iframe.html b/dom/security/test/general/test_same_site_cookies_iframe.html new file mode 100644 index 0000000000..45d5d5830a --- /dev/null +++ b/dom/security/test/general/test_same_site_cookies_iframe.html @@ -0,0 +1,168 @@ + + + + Bug 1454027 - Update SameSite cookie handling inside iframes + + + + + + + + + + diff --git a/dom/security/test/general/test_same_site_cookies_laxByDefault.html b/dom/security/test/general/test_same_site_cookies_laxByDefault.html new file mode 100644 index 0000000000..9fd0d0b704 --- /dev/null +++ b/dom/security/test/general/test_same_site_cookies_laxByDefault.html @@ -0,0 +1,85 @@ + + + + Bug 1551798 - SameSite=lax by default + + + + + + + diff --git a/dom/security/test/general/test_same_site_cookies_redirect.html b/dom/security/test/general/test_same_site_cookies_redirect.html new file mode 100644 index 0000000000..59f98b2263 --- /dev/null +++ b/dom/security/test/general/test_same_site_cookies_redirect.html @@ -0,0 +1,101 @@ + + + + Bug 1453814 - Do not allow same-site cookies for cross origin redirect + + + + + + + + + + diff --git a/dom/security/test/general/test_same_site_cookies_subrequest.html b/dom/security/test/general/test_same_site_cookies_subrequest.html new file mode 100644 index 0000000000..304dbafa9a --- /dev/null +++ b/dom/security/test/general/test_same_site_cookies_subrequest.html @@ -0,0 +1,113 @@ + + + + Bug 1286861 - Test same site cookies on subrequests + + + + + + + + + + diff --git a/dom/security/test/general/test_same_site_cookies_toplevel_nav.html b/dom/security/test/general/test_same_site_cookies_toplevel_nav.html new file mode 100644 index 0000000000..aba825916b --- /dev/null +++ b/dom/security/test/general/test_same_site_cookies_toplevel_nav.html @@ -0,0 +1,117 @@ + + + + Bug 1286861 - Test same site cookies on top-level navigations + + + + + + + + + diff --git a/dom/security/test/general/test_same_site_cookies_toplevel_set_cookie.html b/dom/security/test/general/test_same_site_cookies_toplevel_set_cookie.html new file mode 100644 index 0000000000..cae2a6174e --- /dev/null +++ b/dom/security/test/general/test_same_site_cookies_toplevel_set_cookie.html @@ -0,0 +1,57 @@ + + + + Bug 1454242: Setting samesite cookie should not rely on CookieCommons::IsSameSiteForeign + + + + + + + + + + diff --git a/dom/security/test/general/test_xfo_error_page.html b/dom/security/test/general/test_xfo_error_page.html new file mode 100644 index 0000000000..218413b4f9 --- /dev/null +++ b/dom/security/test/general/test_xfo_error_page.html @@ -0,0 +1,35 @@ + + + + Bug 1626249: Ensure correct display of neterror page for XFO + + + + + + + + + diff --git a/dom/security/test/general/window_nosniff_navigation.html b/dom/security/test/general/window_nosniff_navigation.html new file mode 100644 index 0000000000..1287e451b1 --- /dev/null +++ b/dom/security/test/general/window_nosniff_navigation.html @@ -0,0 +1,96 @@ + + + + Bug 1428473 Support X-Content-Type-Options: nosniff when navigating + + + + + + + + + + + + + +
+ + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dom/security/test/gtest/TestCSPParser.cpp b/dom/security/test/gtest/TestCSPParser.cpp new file mode 100644 index 0000000000..b8a4e986b6 --- /dev/null +++ b/dom/security/test/gtest/TestCSPParser.cpp @@ -0,0 +1,1148 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "gtest/gtest.h" + +#include +#include + +#include "nsIContentSecurityPolicy.h" +#include "nsNetUtil.h" +#include "mozilla/BasePrincipal.h" +#include "mozilla/dom/nsCSPContext.h" +#include "mozilla/gtest/MozAssertions.h" +#include "nsComponentManagerUtils.h" +#include "nsIPrefBranch.h" +#include "nsIPrefService.h" +#include "nsStringFwd.h" + +/* + * Testing the parser is non trivial, especially since we can not call + * parser functionality directly in compiled code tests. + * All the tests (except the fuzzy tests at the end) follow the same schemata: + * a) create an nsIContentSecurityPolicy object + * b) set the selfURI in SetRequestContextWithPrincipal + * c) append one or more policies by calling AppendPolicy + * d) check if the policy count is correct by calling GetPolicyCount + * e) compare the result of the policy with the expected output + * using the struct PolicyTest; + * + * In general we test: + * a) policies that the parser should accept + * b) policies that the parser should reject + * c) policies that are randomly generated (fuzzy tests) + * + * Please note that fuzzy tests are *DISABLED* by default and shold only + * be run *OFFLINE* whenever code in nsCSPParser changes. + * To run fuzzy tests, flip RUN_OFFLINE_TESTS to 1. + * + */ + +#define RUN_OFFLINE_TESTS 0 + +/* + * Offline tests are separated in three different groups: + * * TestFuzzyPolicies - complete random ASCII input + * * TestFuzzyPoliciesIncDir - a directory name followed by random ASCII + * * TestFuzzyPoliciesIncDirLimASCII - a directory name followed by limited + * ASCII which represents more likely user input. + * + * We run each of this categories |kFuzzyRuns| times. + */ + +#if RUN_OFFLINE_TESTS +static const uint32_t kFuzzyRuns = 10000; +#endif + +// For fuzzy testing we actually do not care about the output, +// we just want to make sure that the parser can handle random +// input, therefore we use kFuzzyExpectedPolicyCount to return early. +static const uint32_t kFuzzyExpectedPolicyCount = 111; + +static const uint32_t kMaxPolicyLength = 96; + +struct PolicyTest { + char policy[kMaxPolicyLength]; + char expectedResult[kMaxPolicyLength]; +}; + +nsresult runTest( + uint32_t aExpectedPolicyCount, // this should be 0 for policies which + // should fail to parse + const char* aPolicy, const char* aExpectedResult) { + nsresult rv; + + // we init the csp with http://www.selfuri.com + nsCOMPtr selfURI; + rv = NS_NewURI(getter_AddRefs(selfURI), "http://www.selfuri.com"); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr selfURIPrincipal; + mozilla::OriginAttributes attrs; + selfURIPrincipal = + mozilla::BasePrincipal::CreateContentPrincipal(selfURI, attrs); + NS_ENSURE_TRUE(selfURIPrincipal, NS_ERROR_FAILURE); + + // create a CSP object + nsCOMPtr csp = + do_CreateInstance(NS_CSPCONTEXT_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + // for testing the parser we only need to set a principal which is needed + // to translate the keyword 'self' into an actual URI. + rv = + csp->SetRequestContextWithPrincipal(selfURIPrincipal, selfURI, u""_ns, 0); + NS_ENSURE_SUCCESS(rv, rv); + + // append a policy + nsString policyStr; + policyStr.AssignASCII(aPolicy); + rv = csp->AppendPolicy(policyStr, false, false); + NS_ENSURE_SUCCESS(rv, rv); + + // when executing fuzzy tests we do not care about the actual output + // of the parser, we just want to make sure that the parser is not crashing. + if (aExpectedPolicyCount == kFuzzyExpectedPolicyCount) { + return NS_OK; + } + + // verify that the expected number of policies exists + uint32_t actualPolicyCount; + rv = csp->GetPolicyCount(&actualPolicyCount); + NS_ENSURE_SUCCESS(rv, rv); + if (actualPolicyCount != aExpectedPolicyCount) { + EXPECT_TRUE(false) + << "Actual policy count not equal to expected policy count (" + << actualPolicyCount << " != " << aExpectedPolicyCount + << ") for policy: " << aPolicy; + return NS_ERROR_UNEXPECTED; + } + + // if the expected policy count is 0, we can return, because + // we can not compare any output anyway. Used when parsing + // errornous policies. + if (aExpectedPolicyCount == 0) { + return NS_OK; + } + + // compare the parsed policy against the expected result + nsString parsedPolicyStr; + // checking policy at index 0, which is the one what we appended. + rv = csp->GetPolicyString(0, parsedPolicyStr); + NS_ENSURE_SUCCESS(rv, rv); + + if (!NS_ConvertUTF16toUTF8(parsedPolicyStr).EqualsASCII(aExpectedResult)) { + EXPECT_TRUE(false) << "Actual policy does not match expected policy (" + << NS_ConvertUTF16toUTF8(parsedPolicyStr).get() + << " != " << aExpectedResult << ")"; + return NS_ERROR_UNEXPECTED; + } + + return NS_OK; +} + +// ============================= run Tests ======================== + +nsresult runTestSuite(const PolicyTest* aPolicies, uint32_t aPolicyCount, + uint32_t aExpectedPolicyCount) { + nsresult rv; + nsCOMPtr prefs = do_GetService(NS_PREFSERVICE_CONTRACTID); + + // Add prefs you need to set to parse CSP here, see comments for example + // bool examplePref = false; + if (prefs) { + // prefs->GetBoolPref("security.csp.examplePref", &examplePref); + // prefs->SetBoolPref("security.csp.examplePref", true); + } + + for (uint32_t i = 0; i < aPolicyCount; i++) { + rv = runTest(aExpectedPolicyCount, aPolicies[i].policy, + aPolicies[i].expectedResult); + NS_ENSURE_SUCCESS(rv, rv); + } + + if (prefs) { + // prefs->SetBoolPref("security.csp.examplePref", examplePref); + } + + return NS_OK; +} + +// ============================= TestDirectives ======================== + +TEST(CSPParser, Directives) +{ + static const PolicyTest policies[] = { + // clang-format off + { "connect-src xn--mnchen-3ya.de", + "connect-src http://xn--mnchen-3ya.de"}, + { "default-src http://www.example.com", + "default-src http://www.example.com" }, + { "script-src http://www.example.com", + "script-src http://www.example.com" }, + { "object-src http://www.example.com", + "object-src http://www.example.com" }, + { "style-src http://www.example.com", + "style-src http://www.example.com" }, + { "img-src http://www.example.com", + "img-src http://www.example.com" }, + { "media-src http://www.example.com", + "media-src http://www.example.com" }, + { "frame-src http://www.example.com", + "frame-src http://www.example.com" }, + { "font-src http://www.example.com", + "font-src http://www.example.com" }, + { "connect-src http://www.example.com", + "connect-src http://www.example.com" }, + { "report-uri http://www.example.com", + "report-uri http://www.example.com/" }, + { "script-src 'nonce-correctscriptnonce'", + "script-src 'nonce-correctscriptnonce'" }, + { "script-src 'nonce-a'", + "script-src 'nonce-a'" }, + { "script-src 'sha256-a'", + "script-src 'sha256-a'" }, + { "script-src 'sha256-siVR8vAcqP06h2ppeNwqgjr0yZ6yned4X2VF84j4GmI='", + "script-src 'sha256-siVR8vAcqP06h2ppeNwqgjr0yZ6yned4X2VF84j4GmI='" }, + { "script-src 'nonce-foo' 'unsafe-inline' ", + "script-src 'nonce-foo' 'unsafe-inline'" }, + { "script-src 'nonce-foo' 'strict-dynamic' 'unsafe-inline' https: ", + "script-src 'nonce-foo' 'strict-dynamic' 'unsafe-inline' https:" }, + { "script-src 'nonce-foo' 'strict-dynamic' 'unsafe-inline' 'report-sample' https: ", + "script-src 'nonce-foo' 'strict-dynamic' 'unsafe-inline' 'report-sample' https:" }, + { "default-src 'sha256-siVR8' 'strict-dynamic' 'unsafe-inline' https: ", + "default-src 'sha256-siVR8' 'strict-dynamic' 'unsafe-inline' https:" }, + { "worker-src https://example.com", + "worker-src https://example.com" }, + { "worker-src http://worker.com; frame-src http://frame.com; child-src http://child.com", + "worker-src http://worker.com; frame-src http://frame.com; child-src http://child.com" }, + { "script-src 'unsafe-allow-redirects' http://example.com", + "script-src http://example.com"}, + // clang-format on + }; + + uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest); + ASSERT_NS_SUCCEEDED(runTestSuite(policies, policyCount, 1)); +} + +// ============================= TestKeywords ======================== + +TEST(CSPParser, Keywords) +{ + static const PolicyTest policies[] = { + // clang-format off + { "script-src 'self'", + "script-src 'self'" }, + { "script-src 'unsafe-inline'", + "script-src 'unsafe-inline'" }, + { "script-src 'unsafe-eval'", + "script-src 'unsafe-eval'" }, + { "script-src 'unsafe-inline' 'unsafe-eval'", + "script-src 'unsafe-inline' 'unsafe-eval'" }, + { "script-src 'none'", + "script-src 'none'" }, + { "script-src 'wasm-unsafe-eval'", + "script-src 'wasm-unsafe-eval'" }, + { "img-src 'none'; script-src 'unsafe-eval' 'unsafe-inline'; default-src 'self'", + "img-src 'none'; script-src 'unsafe-eval' 'unsafe-inline'; default-src 'self'" }, + // clang-format on + }; + + uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest); + ASSERT_NS_SUCCEEDED(runTestSuite(policies, policyCount, 1)); +} + +// =================== TestIgnoreUpperLowerCasePolicies ============== + +TEST(CSPParser, IgnoreUpperLowerCasePolicies) +{ + static const PolicyTest policies[] = { + // clang-format off + { "script-src 'SELF'", + "script-src 'self'" }, + { "sCriPt-src 'Unsafe-Inline'", + "script-src 'unsafe-inline'" }, + { "SCRIPT-src 'unsafe-eval'", + "script-src 'unsafe-eval'" }, + { "default-SRC 'unsafe-inline' 'unsafe-eval'", + "default-src 'unsafe-inline' 'unsafe-eval'" }, + { "script-src 'NoNe'", + "script-src 'none'" }, + { "img-sRc 'noNe'; scrIpt-src 'unsafe-EVAL' 'UNSAFE-inline'; deFAULT-src 'Self'", + "img-src 'none'; script-src 'unsafe-eval' 'unsafe-inline'; default-src 'self'" }, + { "default-src HTTP://www.example.com", + "default-src http://www.example.com" }, + { "default-src HTTP://WWW.EXAMPLE.COM", + "default-src http://www.example.com" }, + { "default-src HTTPS://*.example.COM", + "default-src https://*.example.com" }, + { "script-src 'none' test.com;", + "script-src http://test.com" }, + { "script-src 'NoNCE-correctscriptnonce'", + "script-src 'nonce-correctscriptnonce'" }, + { "script-src 'NoncE-NONCENEEDSTOBEUPPERCASE'", + "script-src 'nonce-NONCENEEDSTOBEUPPERCASE'" }, + { "script-src 'SHA256-siVR8vAcqP06h2ppeNwqgjr0yZ6yned4X2VF84j4GmI='", + "script-src 'sha256-siVR8vAcqP06h2ppeNwqgjr0yZ6yned4X2VF84j4GmI='" }, + { "upgrade-INSECURE-requests", + "upgrade-insecure-requests" }, + { "sanDBox alloW-foRMs", + "sandbox allow-forms"}, + // clang-format on + }; + + uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest); + ASSERT_NS_SUCCEEDED(runTestSuite(policies, policyCount, 1)); +} + +// ========================= TestPaths =============================== + +TEST(CSPParser, Paths) +{ + static const PolicyTest policies[] = { + // clang-format off + { "script-src http://www.example.com", + "script-src http://www.example.com" }, + { "script-src http://www.example.com/", + "script-src http://www.example.com/" }, + { "script-src http://www.example.com/path-1", + "script-src http://www.example.com/path-1" }, + { "script-src http://www.example.com/path-1/", + "script-src http://www.example.com/path-1/" }, + { "script-src http://www.example.com/path-1/path_2", + "script-src http://www.example.com/path-1/path_2" }, + { "script-src http://www.example.com/path-1/path_2/", + "script-src http://www.example.com/path-1/path_2/" }, + { "script-src http://www.example.com/path-1/path_2/file.js", + "script-src http://www.example.com/path-1/path_2/file.js" }, + { "script-src http://www.example.com/path-1/path_2/file_1.js", + "script-src http://www.example.com/path-1/path_2/file_1.js" }, + { "script-src http://www.example.com/path-1/path_2/file-2.js", + "script-src http://www.example.com/path-1/path_2/file-2.js" }, + { "script-src http://www.example.com/path-1/path_2/f.js", + "script-src http://www.example.com/path-1/path_2/f.js" }, + { "script-src http://www.example.com:88", + "script-src http://www.example.com:88" }, + { "script-src http://www.example.com:88/", + "script-src http://www.example.com:88/" }, + { "script-src http://www.example.com:88/path-1", + "script-src http://www.example.com:88/path-1" }, + { "script-src http://www.example.com:88/path-1/", + "script-src http://www.example.com:88/path-1/" }, + { "script-src http://www.example.com:88/path-1/path_2", + "script-src http://www.example.com:88/path-1/path_2" }, + { "script-src http://www.example.com:88/path-1/path_2/", + "script-src http://www.example.com:88/path-1/path_2/" }, + { "script-src http://www.example.com:88/path-1/path_2/file.js", + "script-src http://www.example.com:88/path-1/path_2/file.js" }, + { "script-src http://www.example.com:*", + "script-src http://www.example.com:*" }, + { "script-src http://www.example.com:*/", + "script-src http://www.example.com:*/" }, + { "script-src http://www.example.com:*/path-1", + "script-src http://www.example.com:*/path-1" }, + { "script-src http://www.example.com:*/path-1/", + "script-src http://www.example.com:*/path-1/" }, + { "script-src http://www.example.com:*/path-1/path_2", + "script-src http://www.example.com:*/path-1/path_2" }, + { "script-src http://www.example.com:*/path-1/path_2/", + "script-src http://www.example.com:*/path-1/path_2/" }, + { "script-src http://www.example.com:*/path-1/path_2/file.js", + "script-src http://www.example.com:*/path-1/path_2/file.js" }, + { "script-src http://www.example.com#foo", + "script-src http://www.example.com" }, + { "script-src http://www.example.com?foo=bar", + "script-src http://www.example.com" }, + { "script-src http://www.example.com:8888#foo", + "script-src http://www.example.com:8888" }, + { "script-src http://www.example.com:8888?foo", + "script-src http://www.example.com:8888" }, + { "script-src http://www.example.com/#foo", + "script-src http://www.example.com/" }, + { "script-src http://www.example.com/?foo", + "script-src http://www.example.com/" }, + { "script-src http://www.example.com/path-1/file.js#foo", + "script-src http://www.example.com/path-1/file.js" }, + { "script-src http://www.example.com/path-1/file.js?foo", + "script-src http://www.example.com/path-1/file.js" }, + { "script-src http://www.example.com/path-1/file.js?foo#bar", + "script-src http://www.example.com/path-1/file.js" }, + { "report-uri http://www.example.com/", + "report-uri http://www.example.com/" }, + { "report-uri http://www.example.com:8888/asdf", + "report-uri http://www.example.com:8888/asdf" }, + { "report-uri http://www.example.com:8888/path_1/path_2", + "report-uri http://www.example.com:8888/path_1/path_2" }, + { "report-uri http://www.example.com:8888/path_1/path_2/report.sjs&301", + "report-uri http://www.example.com:8888/path_1/path_2/report.sjs&301" }, + { "report-uri /examplepath", + "report-uri http://www.selfuri.com/examplepath" }, + { "connect-src http://www.example.com/foo%3Bsessionid=12%2C34", + "connect-src http://www.example.com/foo;sessionid=12,34" }, + { "connect-src http://www.example.com/foo%3bsessionid=12%2c34", + "connect-src http://www.example.com/foo;sessionid=12,34" }, + { "connect-src http://test.com/pathIncludingAz19-._~!$&'()*+=:@", + "connect-src http://test.com/pathIncludingAz19-._~!$&'()*+=:@" }, + { "script-src http://www.example.com:88/.js", + "script-src http://www.example.com:88/.js" }, + { "script-src https://foo.com/_abc/abc_/_/_a_b_c_", + "script-src https://foo.com/_abc/abc_/_/_a_b_c_" } + // clang-format on + }; + + uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest); + ASSERT_NS_SUCCEEDED(runTestSuite(policies, policyCount, 1)); +} + +// ======================== TestSimplePolicies ======================= + +TEST(CSPParser, SimplePolicies) +{ + static const PolicyTest policies[] = { + // clang-format off + { "frame-src intent:", + "frame-src intent:" }, + { "frame-src intent://host.name", + "frame-src intent://host.name" }, + { "frame-src intent://my.host.link/", + "frame-src intent://my.host.link/" }, + { "default-src *", + "default-src *" }, + { "default-src https:", + "default-src https:" }, + { "default-src https://*", + "default-src https://*" }, + { "default-src *:*", + "default-src http://*:*" }, + { "default-src *:80", + "default-src http://*:80" }, + { "default-src http://*:80", + "default-src http://*:80" }, + { "default-src javascript:", + "default-src javascript:" }, + { "default-src data:", + "default-src data:" }, + { "script-src 'unsafe-eval' 'unsafe-inline' http://www.example.com", + "script-src 'unsafe-eval' 'unsafe-inline' http://www.example.com" }, + { "object-src 'self'", + "object-src 'self'" }, + { "style-src http://www.example.com 'self'", + "style-src http://www.example.com 'self'" }, + { "media-src http://www.example.com http://www.test.com", + "media-src http://www.example.com http://www.test.com" }, + { "connect-src http://www.test.com example.com *.other.com;", + "connect-src http://www.test.com http://example.com http://*.other.com"}, + { "connect-src example.com *.other.com", + "connect-src http://example.com http://*.other.com"}, + { "style-src *.other.com example.com", + "style-src http://*.other.com http://example.com"}, + { "default-src 'self'; img-src *;", + "default-src 'self'; img-src *" }, + { "object-src media1.example.com media2.example.com *.cdn.example.com;", + "object-src http://media1.example.com http://media2.example.com http://*.cdn.example.com" }, + { "script-src trustedscripts.example.com", + "script-src http://trustedscripts.example.com" }, + { "script-src 'self' ; default-src trustedscripts.example.com", + "script-src 'self'; default-src http://trustedscripts.example.com" }, + { "default-src 'none'; report-uri http://localhost:49938/test", + "default-src 'none'; report-uri http://localhost:49938/test" }, + { " ; default-src abc", + "default-src http://abc" }, + { " ; ; ; ; default-src abc ; ; ; ;", + "default-src http://abc" }, + { "script-src 'none' 'none' 'none';", + "script-src 'none'" }, + { "script-src http://www.example.com/path-1//", + "script-src http://www.example.com/path-1//" }, + { "script-src http://www.example.com/path-1//path_2", + "script-src http://www.example.com/path-1//path_2" }, + { "default-src 127.0.0.1", + "default-src http://127.0.0.1" }, + { "default-src 127.0.0.1:*", + "default-src http://127.0.0.1:*" }, + { "default-src -; ", + "default-src http://-" }, + { "script-src 1", + "script-src http://1" }, + { "upgrade-insecure-requests", + "upgrade-insecure-requests" }, + { "upgrade-insecure-requests https:", + "upgrade-insecure-requests" }, + { "sandbox allow-scripts allow-forms ", + "sandbox allow-scripts allow-forms" }, + // clang-format on + }; + + uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest); + ASSERT_NS_SUCCEEDED(runTestSuite(policies, policyCount, 1)); +} + +// =================== TestPoliciesWithInvalidSrc ==================== + +TEST(CSPParser, PoliciesWithInvalidSrc) +{ + static const PolicyTest policies[] = { + // clang-format off + { "script-src 'self'; SCRIPT-SRC http://www.example.com", + "script-src 'self'" }, + { "script-src 'none' test.com; script-src example.com", + "script-src http://test.com" }, + { "default-src **", + "default-src 'none'" }, + { "default-src 'self", + "default-src 'none'" }, + { "default-src 'unsafe-inlin' ", + "default-src 'none'" }, + { "default-src */", + "default-src 'none'" }, + { "default-src", + "default-src 'none'" }, + { "default-src 'unsafe-inlin' ", + "default-src 'none'" }, + { "default-src :88", + "default-src 'none'" }, + { "script-src abc::::::88", + "script-src 'none'" }, + { "script-src *.*:*", + "script-src 'none'" }, + { "img-src *::88", + "img-src 'none'" }, + { "object-src http://localhost:", + "object-src 'none'" }, + { "script-src test..com", + "script-src 'none'" }, + { "script-src sub1.sub2.example+", + "script-src 'none'" }, + { "script-src http://www.example.com//", + "script-src 'none'" }, + { "script-src http://www.example.com:88path-1/", + "script-src 'none'" }, + { "script-src http://www.example.com:88//", + "script-src 'none'" }, + { "script-src http://www.example.com:88//path-1", + "script-src 'none'" }, + { "script-src http://www.example.com:88//path-1", + "script-src 'none'" }, + { "script-src http://www.example.com:88.js", + "script-src 'none'" }, + { "script-src http://www.example.com:*.js", + "script-src 'none'" }, + { "script-src http://www.example.com:*.", + "script-src 'none'" }, + { "script-src 'nonce-{invalid}'", + "script-src 'none'" }, + { "script-src 'sha256-{invalid}'", + "script-src 'none'" }, + { "script-src 'nonce-in$valid'", + "script-src 'none'" }, + { "script-src 'sha256-in$valid'", + "script-src 'none'" }, + { "script-src 'nonce-invalid==='", + "script-src 'none'" }, + { "script-src 'sha256-invalid==='", + "script-src 'none'" }, + { "script-src 'nonce-==='", + "script-src 'none'" }, + { "script-src 'sha256-==='", + "script-src 'none'" }, + { "script-src 'nonce-=='", + "script-src 'none'" }, + { "script-src 'sha256-=='", + "script-src 'none'" }, + { "script-src 'nonce-='", + "script-src 'none'" }, + { "script-src 'sha256-='", + "script-src 'none'" }, + { "script-src 'nonce-'", + "script-src 'none'" }, + { "script-src 'sha256-'", + "script-src 'none'" }, + { "connect-src http://www.example.com/foo%zz;", + "connect-src 'none'" }, + { "script-src https://foo.com/%$", + "script-src 'none'" }, + { "sandbox foo", + "sandbox"}, + // clang-format on + }; + + // amount of tests - 1, because the latest should be ignored. + uint32_t policyCount = (sizeof(policies) / sizeof(PolicyTest)) - 1; + ASSERT_NS_SUCCEEDED(runTestSuite(policies, policyCount, 1)); +} + +// ============================= TestBadPolicies ======================= + +TEST(CSPParser, BadPolicies) +{ + static const PolicyTest policies[] = { + // clang-format off + { "script-sr 'self", "" }, + { "", "" }, + { "; ; ; ; ; ; ;", "" }, + { "defaut-src asdf", "" }, + { "default-src: aaa", "" }, + { "asdf http://test.com", ""}, + { "report-uri", ""}, + { "report-uri http://:foo", ""}, + { "require-sri-for", ""}, + { "require-sri-for style", ""}, + // clang-format on + }; + + uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest); + ASSERT_NS_SUCCEEDED(runTestSuite(policies, policyCount, 0)); +} + +// ======================= TestGoodGeneratedPolicies ================= + +TEST(CSPParser, GoodGeneratedPolicies) +{ + static const PolicyTest policies[] = { + // clang-format off + { "default-src 'self'; img-src *", + "default-src 'self'; img-src *" }, + { "report-uri /policy", + "report-uri http://www.selfuri.com/policy"}, + { "img-src *", + "img-src *" }, + { "media-src foo.bar", + "media-src http://foo.bar" }, + { "frame-src *.bar", + "frame-src http://*.bar" }, + { "font-src com", + "font-src http://com" }, + { "connect-src f00b4r.com", + "connect-src http://f00b4r.com" }, + { "script-src *.a.b.c", + "script-src http://*.a.b.c" }, + { "object-src *.b.c", + "object-src http://*.b.c" }, + { "style-src a.b.c", + "style-src http://a.b.c" }, + { "img-src a.com", + "img-src http://a.com" }, + { "media-src http://abc.com", + "media-src http://abc.com" }, + { "frame-src a2-c.com", + "frame-src http://a2-c.com" }, + { "font-src https://a.com", + "font-src https://a.com" }, + { "connect-src *.a.com", + "connect-src http://*.a.com" }, + { "default-src a.com:23", + "default-src http://a.com:23" }, + { "script-src https://a.com:200", + "script-src https://a.com:200" }, + { "object-src data:", + "object-src data:" }, + { "style-src javascript:", + "style-src javascript:" }, + { "frame-src https://foobar.com:443", + "frame-src https://foobar.com:443" }, + { "font-src https://a.com:443", + "font-src https://a.com:443" }, + { "connect-src http://a.com:80", + "connect-src http://a.com:80" }, + { "default-src http://foobar.com", + "default-src http://foobar.com" }, + { "script-src https://foobar.com", + "script-src https://foobar.com" }, + { "style-src 'none'", + "style-src 'none'" }, + { "img-src foo.bar:21 https://ras.bar", + "img-src http://foo.bar:21 https://ras.bar" }, + { "media-src http://foo.bar:21 https://ras.bar:443", + "media-src http://foo.bar:21 https://ras.bar:443" }, + { "frame-src http://self.com:80", + "frame-src http://self.com:80" }, + { "font-src http://self.com", + "font-src http://self.com" }, + { "connect-src https://foo.com http://bar.com:88", + "connect-src https://foo.com http://bar.com:88" }, + { "default-src * https://bar.com 'none'", + "default-src * https://bar.com" }, + { "script-src *.foo.com", + "script-src http://*.foo.com" }, + { "object-src http://b.com", + "object-src http://b.com" }, + { "style-src http://bar.com:88", + "style-src http://bar.com:88" }, + { "img-src https://bar.com:88", + "img-src https://bar.com:88" }, + { "media-src http://bar.com:443", + "media-src http://bar.com:443" }, + { "frame-src https://foo.com:88", + "frame-src https://foo.com:88" }, + { "font-src http://foo.com", + "font-src http://foo.com" }, + { "connect-src http://x.com:23", + "connect-src http://x.com:23" }, + { "default-src http://barbaz.com", + "default-src http://barbaz.com" }, + { "script-src http://somerandom.foo.com", + "script-src http://somerandom.foo.com" }, + { "default-src *", + "default-src *" }, + { "style-src http://bar.com:22", + "style-src http://bar.com:22" }, + { "img-src https://foo.com:443", + "img-src https://foo.com:443" }, + { "script-src https://foo.com; ", + "script-src https://foo.com" }, + { "img-src bar.com:*", + "img-src http://bar.com:*" }, + { "font-src https://foo.com:400", + "font-src https://foo.com:400" }, + { "connect-src http://bar.com:400", + "connect-src http://bar.com:400" }, + { "default-src http://evil.com", + "default-src http://evil.com" }, + { "script-src https://evil.com:100", + "script-src https://evil.com:100" }, + { "default-src bar.com; script-src https://foo.com", + "default-src http://bar.com; script-src https://foo.com" }, + { "default-src 'self'; script-src 'self' https://*:*", + "default-src 'self'; script-src 'self' https://*:*" }, + { "img-src http://self.com:34", + "img-src http://self.com:34" }, + { "media-src http://subd.self.com:34", + "media-src http://subd.self.com:34" }, + { "default-src 'none'", + "default-src 'none'" }, + { "connect-src http://self", + "connect-src http://self" }, + { "default-src http://foo", + "default-src http://foo" }, + { "script-src http://foo:80", + "script-src http://foo:80" }, + { "object-src http://bar", + "object-src http://bar" }, + { "style-src http://three:80", + "style-src http://three:80" }, + { "img-src https://foo:400", + "img-src https://foo:400" }, + { "media-src https://self:34", + "media-src https://self:34" }, + { "frame-src https://bar", + "frame-src https://bar" }, + { "font-src http://three:81", + "font-src http://three:81" }, + { "connect-src https://three:81", + "connect-src https://three:81" }, + { "script-src http://self.com:80/foo", + "script-src http://self.com:80/foo" }, + { "object-src http://self.com/foo", + "object-src http://self.com/foo" }, + { "report-uri /report.py", + "report-uri http://www.selfuri.com/report.py"}, + { "img-src http://foo.org:34/report.py", + "img-src http://foo.org:34/report.py" }, + { "media-src foo/bar/report.py", + "media-src http://foo/bar/report.py" }, + { "report-uri /", + "report-uri http://www.selfuri.com/"}, + { "font-src https://self.com/report.py", + "font-src https://self.com/report.py" }, + { "connect-src https://foo.com/report.py", + "connect-src https://foo.com/report.py" }, + { "default-src *; report-uri http://www.reporturi.com/", + "default-src *; report-uri http://www.reporturi.com/" }, + { "default-src http://first.com", + "default-src http://first.com" }, + { "script-src http://second.com", + "script-src http://second.com" }, + { "object-src http://third.com", + "object-src http://third.com" }, + { "style-src https://foobar.com:4443", + "style-src https://foobar.com:4443" }, + { "img-src http://foobar.com:4443", + "img-src http://foobar.com:4443" }, + { "media-src bar.com", + "media-src http://bar.com" }, + { "frame-src http://bar.com", + "frame-src http://bar.com" }, + { "font-src http://self.com/", + "font-src http://self.com/" }, + { "script-src 'self'", + "script-src 'self'" }, + { "default-src http://self.com/foo.png", + "default-src http://self.com/foo.png" }, + { "script-src http://self.com/foo.js", + "script-src http://self.com/foo.js" }, + { "object-src http://bar.com/foo.js", + "object-src http://bar.com/foo.js" }, + { "style-src http://FOO.COM", + "style-src http://foo.com" }, + { "img-src HTTP", + "img-src http://http" }, + { "media-src http", + "media-src http://http" }, + { "frame-src 'SELF'", + "frame-src 'self'" }, + { "DEFAULT-src 'self';", + "default-src 'self'" }, + { "default-src 'self' http://FOO.COM", + "default-src 'self' http://foo.com" }, + { "default-src 'self' HTTP://foo.com", + "default-src 'self' http://foo.com" }, + { "default-src 'NONE'", + "default-src 'none'" }, + { "script-src policy-uri ", + "script-src http://policy-uri" }, + { "img-src 'self'; ", + "img-src 'self'" }, + { "frame-ancestors foo-bar.com", + "frame-ancestors http://foo-bar.com" }, + { "frame-ancestors http://a.com", + "frame-ancestors http://a.com" }, + { "frame-ancestors 'self'", + "frame-ancestors 'self'" }, + { "frame-ancestors http://self.com:88", + "frame-ancestors http://self.com:88" }, + { "frame-ancestors http://a.b.c.d.e.f.g.h.i.j.k.l.x.com", + "frame-ancestors http://a.b.c.d.e.f.g.h.i.j.k.l.x.com" }, + { "frame-ancestors https://self.com:34", + "frame-ancestors https://self.com:34" }, + { "frame-ancestors http://sampleuser:samplepass@example.com", + "frame-ancestors 'none'" }, + { "default-src 'none'; frame-ancestors 'self'", + "default-src 'none'; frame-ancestors 'self'" }, + { "frame-ancestors http://self:80", + "frame-ancestors http://self:80" }, + { "frame-ancestors http://self.com/bar", + "frame-ancestors http://self.com/bar" }, + { "default-src 'self'; frame-ancestors 'self'", + "default-src 'self'; frame-ancestors 'self'" }, + { "frame-ancestors http://bar.com/foo.png", + "frame-ancestors http://bar.com/foo.png" }, + // clang-format on + }; + + uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest); + ASSERT_NS_SUCCEEDED(runTestSuite(policies, policyCount, 1)); +} + +// ==================== TestBadGeneratedPolicies ==================== + +TEST(CSPParser, BadGeneratedPolicies) +{ + static const PolicyTest policies[] = { + // clang-format off + { "foo.*.bar", ""}, + { "foo!bar.com", ""}, + { "x.*.a.com", ""}, + { "a#2-c.com", ""}, + { "http://foo.com:bar.com:23", ""}, + { "f!oo.bar", ""}, + { "ht!ps://f-oo.bar", ""}, + { "https://f-oo.bar:3f", ""}, + { "**", ""}, + { "*a", ""}, + { "http://username:password@self.com/foo", ""}, + { "http://other:pass1@self.com/foo", ""}, + { "http://user1:pass1@self.com/foo", ""}, + { "http://username:password@self.com/bar", ""}, + // clang-format on + }; + + uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest); + ASSERT_NS_SUCCEEDED(runTestSuite(policies, policyCount, 0)); +} + +// ============ TestGoodGeneratedPoliciesForPathHandling ============= + +TEST(CSPParser, GoodGeneratedPoliciesForPathHandling) +{ + // Once bug 808292 (Implement path-level host-source matching to CSP) + // lands we have to update the expected output to include the parsed path + + static const PolicyTest policies[] = { + // clang-format off + { "img-src http://test1.example.com", + "img-src http://test1.example.com" }, + { "img-src http://test1.example.com/", + "img-src http://test1.example.com/" }, + { "img-src http://test1.example.com/path-1", + "img-src http://test1.example.com/path-1" }, + { "img-src http://test1.example.com/path-1/", + "img-src http://test1.example.com/path-1/" }, + { "img-src http://test1.example.com/path-1/path_2/", + "img-src http://test1.example.com/path-1/path_2/" }, + { "img-src http://test1.example.com/path-1/path_2/file.js", + "img-src http://test1.example.com/path-1/path_2/file.js" }, + { "img-src http://test1.example.com/path-1/path_2/file_1.js", + "img-src http://test1.example.com/path-1/path_2/file_1.js" }, + { "img-src http://test1.example.com/path-1/path_2/file-2.js", + "img-src http://test1.example.com/path-1/path_2/file-2.js" }, + { "img-src http://test1.example.com/path-1/path_2/f.js", + "img-src http://test1.example.com/path-1/path_2/f.js" }, + { "img-src http://test1.example.com/path-1/path_2/f.oo.js", + "img-src http://test1.example.com/path-1/path_2/f.oo.js" }, + { "img-src test1.example.com", + "img-src http://test1.example.com" }, + { "img-src test1.example.com/", + "img-src http://test1.example.com/" }, + { "img-src test1.example.com/path-1", + "img-src http://test1.example.com/path-1" }, + { "img-src test1.example.com/path-1/", + "img-src http://test1.example.com/path-1/" }, + { "img-src test1.example.com/path-1/path_2/", + "img-src http://test1.example.com/path-1/path_2/" }, + { "img-src test1.example.com/path-1/path_2/file.js", + "img-src http://test1.example.com/path-1/path_2/file.js" }, + { "img-src test1.example.com/path-1/path_2/file_1.js", + "img-src http://test1.example.com/path-1/path_2/file_1.js" }, + { "img-src test1.example.com/path-1/path_2/file-2.js", + "img-src http://test1.example.com/path-1/path_2/file-2.js" }, + { "img-src test1.example.com/path-1/path_2/f.js", + "img-src http://test1.example.com/path-1/path_2/f.js" }, + { "img-src test1.example.com/path-1/path_2/f.oo.js", + "img-src http://test1.example.com/path-1/path_2/f.oo.js" }, + { "img-src *.example.com", + "img-src http://*.example.com" }, + { "img-src *.example.com/", + "img-src http://*.example.com/" }, + { "img-src *.example.com/path-1", + "img-src http://*.example.com/path-1" }, + { "img-src *.example.com/path-1/", + "img-src http://*.example.com/path-1/" }, + { "img-src *.example.com/path-1/path_2/", + "img-src http://*.example.com/path-1/path_2/" }, + { "img-src *.example.com/path-1/path_2/file.js", + "img-src http://*.example.com/path-1/path_2/file.js" }, + { "img-src *.example.com/path-1/path_2/file_1.js", + "img-src http://*.example.com/path-1/path_2/file_1.js" }, + { "img-src *.example.com/path-1/path_2/file-2.js", + "img-src http://*.example.com/path-1/path_2/file-2.js" }, + { "img-src *.example.com/path-1/path_2/f.js", + "img-src http://*.example.com/path-1/path_2/f.js" }, + { "img-src *.example.com/path-1/path_2/f.oo.js", + "img-src http://*.example.com/path-1/path_2/f.oo.js" }, + { "img-src test1.example.com:80", + "img-src http://test1.example.com:80" }, + { "img-src test1.example.com:80/", + "img-src http://test1.example.com:80/" }, + { "img-src test1.example.com:80/path-1", + "img-src http://test1.example.com:80/path-1" }, + { "img-src test1.example.com:80/path-1/", + "img-src http://test1.example.com:80/path-1/" }, + { "img-src test1.example.com:80/path-1/path_2", + "img-src http://test1.example.com:80/path-1/path_2" }, + { "img-src test1.example.com:80/path-1/path_2/", + "img-src http://test1.example.com:80/path-1/path_2/" }, + { "img-src test1.example.com:80/path-1/path_2/file.js", + "img-src http://test1.example.com:80/path-1/path_2/file.js" }, + { "img-src test1.example.com:80/path-1/path_2/f.ile.js", + "img-src http://test1.example.com:80/path-1/path_2/f.ile.js" }, + { "img-src test1.example.com:*", + "img-src http://test1.example.com:*" }, + { "img-src test1.example.com:*/", + "img-src http://test1.example.com:*/" }, + { "img-src test1.example.com:*/path-1", + "img-src http://test1.example.com:*/path-1" }, + { "img-src test1.example.com:*/path-1/", + "img-src http://test1.example.com:*/path-1/" }, + { "img-src test1.example.com:*/path-1/path_2", + "img-src http://test1.example.com:*/path-1/path_2" }, + { "img-src test1.example.com:*/path-1/path_2/", + "img-src http://test1.example.com:*/path-1/path_2/" }, + { "img-src test1.example.com:*/path-1/path_2/file.js", + "img-src http://test1.example.com:*/path-1/path_2/file.js" }, + { "img-src test1.example.com:*/path-1/path_2/f.ile.js", + "img-src http://test1.example.com:*/path-1/path_2/f.ile.js" }, + { "img-src http://test1.example.com/abc//", + "img-src http://test1.example.com/abc//" }, + { "img-src https://test1.example.com/abc/def//", + "img-src https://test1.example.com/abc/def//" }, + { "img-src https://test1.example.com/abc/def/ghi//", + "img-src https://test1.example.com/abc/def/ghi//" }, + { "img-src http://test1.example.com:80/abc//", + "img-src http://test1.example.com:80/abc//" }, + { "img-src https://test1.example.com:80/abc/def//", + "img-src https://test1.example.com:80/abc/def//" }, + { "img-src https://test1.example.com:80/abc/def/ghi//", + "img-src https://test1.example.com:80/abc/def/ghi//" }, + { "img-src https://test1.example.com/abc////////////def/", + "img-src https://test1.example.com/abc////////////def/" }, + { "img-src https://test1.example.com/abc////////////", + "img-src https://test1.example.com/abc////////////" }, + // clang-format on + }; + + uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest); + ASSERT_NS_SUCCEEDED(runTestSuite(policies, policyCount, 1)); +} + +// ============== TestBadGeneratedPoliciesForPathHandling ============ + +TEST(CSPParser, BadGeneratedPoliciesForPathHandling) +{ + static const PolicyTest policies[] = { + // clang-format off + { "img-src test1.example.com:88path-1/", + "img-src 'none'" }, + { "img-src test1.example.com:80.js", + "img-src 'none'" }, + { "img-src test1.example.com:*.js", + "img-src 'none'" }, + { "img-src test1.example.com:*.", + "img-src 'none'" }, + { "img-src http://test1.example.com//", + "img-src 'none'" }, + { "img-src http://test1.example.com:80//", + "img-src 'none'" }, + { "img-src http://test1.example.com:80abc", + "img-src 'none'" }, + // clang-format on + }; + + uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest); + ASSERT_NS_SUCCEEDED(runTestSuite(policies, policyCount, 1)); +} + +// ======================== TestFuzzyPolicies ======================== + +// Use a policy, eliminate one character at a time, +// and feed it as input to the parser. + +TEST(CSPParser, ShorteningPolicies) +{ + char pol[] = + "default-src http://www.sub1.sub2.example.com:88/path1/path2/ " + "'unsafe-inline' 'none'"; + uint32_t len = static_cast(sizeof(pol)); + + PolicyTest testPol[1]; + memset(&testPol[0].policy, '\0', kMaxPolicyLength * sizeof(char)); + + while (--len) { + memset(&testPol[0].policy, '\0', kMaxPolicyLength * sizeof(char)); + memcpy(&testPol[0].policy, &pol, len * sizeof(char)); + ASSERT_TRUE( + NS_SUCCEEDED(runTestSuite(testPol, 1, kFuzzyExpectedPolicyCount))); + } +} + +// ============================= TestFuzzyPolicies =================== + +// We generate kFuzzyRuns inputs by (pseudo) randomly picking from the 128 +// ASCII characters; feed them to the parser and verfy that the parser +// handles the input gracefully. +// +// Please note, that by using srand(0) we get deterministic results! + +#if RUN_OFFLINE_TESTS + +TEST(CSPParser, FuzzyPolicies) +{ + // init srand with 0 so we get same results + srand(0); + + PolicyTest testPol[1]; + memset(&testPol[0].policy, '\0', kMaxPolicyLength); + + for (uint32_t index = 0; index < kFuzzyRuns; index++) { + // randomly select the length of the next policy + uint32_t polLength = rand() % kMaxPolicyLength; + // reset memory of the policy string + memset(&testPol[0].policy, '\0', kMaxPolicyLength * sizeof(char)); + + for (uint32_t i = 0; i < polLength; i++) { + // fill the policy array with random ASCII chars + testPol[0].policy[i] = static_cast(rand() % 128); + } + ASSERT_TRUE( + NS_SUCCEEDED(runTestSuite(testPol, 1, kFuzzyExpectedPolicyCount))); + } +} + +#endif + +// ======================= TestFuzzyPoliciesIncDir =================== + +// In a similar fashion as in TestFuzzyPolicies, we again (pseudo) randomly +// generate input for the parser, but this time also include a valid directive +// followed by the random input. + +#if RUN_OFFLINE_TESTS + +TEST(CSPParser, FuzzyPoliciesIncDir) +{ + // init srand with 0 so we get same results + srand(0); + + PolicyTest testPol[1]; + memset(&testPol[0].policy, '\0', kMaxPolicyLength); + + char defaultSrc[] = "default-src "; + int defaultSrcLen = sizeof(defaultSrc) - 1; + // copy default-src into the policy array + memcpy(&testPol[0].policy, &defaultSrc, (defaultSrcLen * sizeof(char))); + + for (uint32_t index = 0; index < kFuzzyRuns; index++) { + // randomly select the length of the next policy + uint32_t polLength = rand() % (kMaxPolicyLength - defaultSrcLen); + // reset memory of the policy string, but leave default-src. + memset((&(testPol[0].policy) + (defaultSrcLen * sizeof(char))), '\0', + (kMaxPolicyLength - defaultSrcLen) * sizeof(char)); + + // do not start at index 0 so we do not overwrite 'default-src' + for (uint32_t i = defaultSrcLen; i < polLength; i++) { + // fill the policy array with random ASCII chars + testPol[0].policy[i] = static_cast(rand() % 128); + } + ASSERT_TRUE( + NS_SUCCEEDED(runTestSuite(testPol, 1, kFuzzyExpectedPolicyCount))); + } +} + +#endif + +// ====================== TestFuzzyPoliciesIncDirLimASCII ============ + +// Same as TestFuzzyPoliciesIncDir() but using limited ASCII, +// which represents more likely input. + +#if RUN_OFFLINE_TESTS + +TEST(CSPParser, FuzzyPoliciesIncDirLimASCII) +{ + char input[] = + "1234567890" + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWZYZ" + "!@#^&*()-+_="; + + // init srand with 0 so we get same results + srand(0); + + PolicyTest testPol[1]; + memset(&testPol[0].policy, '\0', kMaxPolicyLength); + + char defaultSrc[] = "default-src "; + int defaultSrcLen = sizeof(defaultSrc) - 1; + // copy default-src into the policy array + memcpy(&testPol[0].policy, &defaultSrc, (defaultSrcLen * sizeof(char))); + + for (uint32_t index = 0; index < kFuzzyRuns; index++) { + // randomly select the length of the next policy + uint32_t polLength = rand() % (kMaxPolicyLength - defaultSrcLen); + // reset memory of the policy string, but leave default-src. + memset((&(testPol[0].policy) + (defaultSrcLen * sizeof(char))), '\0', + (kMaxPolicyLength - defaultSrcLen) * sizeof(char)); + + // do not start at index 0 so we do not overwrite 'default-src' + for (uint32_t i = defaultSrcLen; i < polLength; i++) { + // fill the policy array with chars from the pre-defined input + uint32_t inputIndex = rand() % sizeof(input); + testPol[0].policy[i] = input[inputIndex]; + } + ASSERT_TRUE( + NS_SUCCEEDED(runTestSuite(testPol, 1, kFuzzyExpectedPolicyCount))); + } +} +#endif diff --git a/dom/security/test/gtest/TestFilenameEvalParser.cpp b/dom/security/test/gtest/TestFilenameEvalParser.cpp new file mode 100644 index 0000000000..60683007ca --- /dev/null +++ b/dom/security/test/gtest/TestFilenameEvalParser.cpp @@ -0,0 +1,453 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "gtest/gtest.h" + +#include +#include + +#include "nsContentSecurityUtils.h" +#include "nsStringFwd.h" + +#include "mozilla/ExtensionPolicyService.h" +#include "mozilla/dom/ScriptSettings.h" +#include "mozilla/dom/SimpleGlobalObject.h" +#include "mozilla/extensions/WebExtensionPolicy.h" + +static constexpr auto kChromeURI = "chromeuri"_ns; +static constexpr auto kResourceURI = "resourceuri"_ns; +static constexpr auto kBlobUri = "bloburi"_ns; +static constexpr auto kDataUri = "dataurl"_ns; +static constexpr auto kAboutUri = "abouturi"_ns; +static constexpr auto kSingleString = "singlestring"_ns; +static constexpr auto kMozillaExtensionFile = "mozillaextension_file"_ns; +static constexpr auto kExtensionURI = "extension_uri"_ns; +static constexpr auto kSuspectedUserChromeJS = "suspectedUserChromeJS"_ns; +#if defined(XP_WIN) +static constexpr auto kSanitizedWindowsURL = "sanitizedWindowsURL"_ns; +static constexpr auto kSanitizedWindowsPath = "sanitizedWindowsPath"_ns; +#endif +static constexpr auto kOther = "other"_ns; + +#define ASSERT_AND_PRINT(first, second, condition) \ + fprintf(stderr, "First: %s\n", first.get()); \ + fprintf(stderr, "Second: %s\n", NS_ConvertUTF16toUTF8(second).get()); \ + ASSERT_TRUE((condition)); +// Usage: ASSERT_AND_PRINT(ret.first, ret.second.value(), ... + +#define ASSERT_AND_PRINT_FIRST(first, condition) \ + fprintf(stderr, "First: %s\n", (first).get()); \ + ASSERT_TRUE((condition)); +// Usage: ASSERT_AND_PRINT_FIRST(ret.first, ... + +TEST(FilenameEvalParser, ResourceChrome) +{ + { + constexpr auto str = u"chrome://firegestures/content/browser.js"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, false); + ASSERT_TRUE(ret.first == kChromeURI && ret.second.isSome() && + ret.second.value() == str); + } + { + constexpr auto str = u"resource://firegestures/content/browser.js"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, false); + ASSERT_TRUE(ret.first == kResourceURI && ret.second.isSome() && + ret.second.value() == str); + } +} + +TEST(FilenameEvalParser, BlobData) +{ + { + constexpr auto str = u"blob://000-000"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, false); + ASSERT_TRUE(ret.first == kBlobUri && !ret.second.isSome()); + } + { + constexpr auto str = u"blob:000-000"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, false); + ASSERT_TRUE(ret.first == kBlobUri && !ret.second.isSome()); + } + { + constexpr auto str = u"data://blahblahblah"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, false); + ASSERT_TRUE(ret.first == kDataUri && !ret.second.isSome()); + } + { + constexpr auto str = u"data:blahblahblah"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, false); + ASSERT_TRUE(ret.first == kDataUri && !ret.second.isSome()); + } +} + +TEST(FilenameEvalParser, MozExtension) +{ + { // Test shield.mozilla.org replacing + constexpr auto str = + u"jar:file:///c:/users/bob/appdata/roaming/mozilla/firefox/profiles/" + u"foo/" + "extensions/federated-learning@shield.mozilla.org.xpi!/experiments/" + "study/api.js"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, false); + ASSERT_TRUE(ret.first == kMozillaExtensionFile && + ret.second.value() == + u"federated-learning@s!/experiments/study/api.js"_ns); + } + { // Test mozilla.org replacing + constexpr auto str = + u"jar:file:///c:/users/bob/appdata/roaming/mozilla/firefox/profiles/" + u"foo/" + "extensions/federated-learning@shigeld.mozilla.org.xpi!/experiments/" + "study/api.js"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, false); + ASSERT_TRUE( + ret.first == kMozillaExtensionFile && + ret.second.value() == + nsLiteralString( + u"federated-learning@shigeld.m!/experiments/study/api.js")); + } + { // Test truncating + constexpr auto str = + u"jar:file:///c:/users/bob/appdata/roaming/mozilla/firefox/profiles/" + u"foo/" + "extensions/federated-learning@shigeld.mozilla.org.xpi!/experiments/" + "study/apiiiiiiiiiiiiiiiiiiiiiiiiiiiiii.js"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, false); + ASSERT_TRUE(ret.first == kMozillaExtensionFile && + ret.second.value() == + u"federated-learning@shigeld.m!/experiments/" + "study/apiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"_ns); + } +} + +TEST(FilenameEvalParser, UserChromeJS) +{ + { + constexpr auto str = u"firegestures/content/browser.uc.js"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, false); + ASSERT_TRUE(ret.first == kSuspectedUserChromeJS && !ret.second.isSome()); + } + { + constexpr auto str = u"firegestures/content/browser.uc.js?"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, false); + ASSERT_TRUE(ret.first == kSuspectedUserChromeJS && !ret.second.isSome()); + } + { + constexpr auto str = u"firegestures/content/browser.uc.js?243244224"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, false); + ASSERT_TRUE(ret.first == kSuspectedUserChromeJS && !ret.second.isSome()); + } + { + constexpr auto str = + u"file:///b:/fxprofiles/mark/chrome/" + "addbookmarkherewithmiddleclick.uc.js?1558444389291"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, false); + ASSERT_TRUE(ret.first == kSuspectedUserChromeJS && !ret.second.isSome()); + } +} + +TEST(FilenameEvalParser, SingleFile) +{ + { + constexpr auto str = u"browser.uc.js?2456"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, false); + ASSERT_TRUE(ret.first == kSingleString && ret.second.isSome() && + ret.second.value() == str); + } + { + constexpr auto str = u"debugger"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, false); + ASSERT_TRUE(ret.first == kSingleString && ret.second.isSome() && + ret.second.value() == str); + } +} + +TEST(FilenameEvalParser, Other) +{ + { + constexpr auto str = u"firegestures--content"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, false); + ASSERT_TRUE(ret.first == kOther && !ret.second.isSome()); + } + { + constexpr auto str = u"gallop://thing/fire"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, false); +#if defined(XP_WIN) + ASSERT_TRUE(ret.first == kSanitizedWindowsURL && + ret.second.value() == u"gallop"_ns); +#else + ASSERT_TRUE(ret.first == kOther && !ret.second.isSome()); +#endif + } + { + constexpr auto str = u"gallop://fire"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, false); +#if defined(XP_WIN) + ASSERT_TRUE(ret.first == kSanitizedWindowsURL && + ret.second.value() == u"gallop"_ns); +#else + ASSERT_TRUE(ret.first == kOther && !ret.second.isSome()); +#endif + } + { + constexpr auto str = u"firegestures/content"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, false); +#if defined(XP_WIN) + ASSERT_TRUE(ret.first == kSanitizedWindowsPath && + ret.second.value() == u"content"_ns); +#else + ASSERT_TRUE(ret.first == kOther && !ret.second.isSome()); +#endif + } + { + constexpr auto str = u"firegestures\\content"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, false); +#if defined(XP_WIN) + ASSERT_TRUE(ret.first == kSanitizedWindowsPath && + ret.second.value() == u"content"_ns); +#else + ASSERT_TRUE(ret.first == kOther && !ret.second.isSome()); +#endif + } + { + constexpr auto str = u"/home/tom/files/thing"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, false); +#if defined(XP_WIN) + ASSERT_TRUE(ret.first == kSanitizedWindowsPath && + ret.second.value() == u"thing"_ns); +#else + ASSERT_TRUE(ret.first == kOther && !ret.second.isSome()); +#endif + } + { + constexpr auto str = u"file://c/uers/tom/file.txt"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, false); +#if defined(XP_WIN) + ASSERT_TRUE(ret.first == kSanitizedWindowsURL && + ret.second.value() == u"file://.../file.txt"_ns); +#else + ASSERT_TRUE(ret.first == kOther && !ret.second.isSome()); +#endif + } + { + constexpr auto str = u"c:/uers/tom/file.txt"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, false); +#if defined(XP_WIN) + ASSERT_TRUE(ret.first == kSanitizedWindowsPath && + ret.second.value() == u"file.txt"_ns); +#else + ASSERT_TRUE(ret.first == kOther && !ret.second.isSome()); +#endif + } + { + constexpr auto str = u"http://example.com/"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, false); +#if defined(XP_WIN) + ASSERT_TRUE(ret.first == kSanitizedWindowsURL && + ret.second.value() == u"http"_ns); +#else + ASSERT_TRUE(ret.first == kOther && !ret.second.isSome()); +#endif + } + { + constexpr auto str = u"http://example.com/thing.html"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, false); +#if defined(XP_WIN) + ASSERT_TRUE(ret.first == kSanitizedWindowsURL && + ret.second.value() == u"http"_ns); +#else + ASSERT_TRUE(ret.first == kOther && !ret.second.isSome()); +#endif + } +} + +TEST(FilenameEvalParser, WebExtensionPathParser) +{ + { + // Set up an Extension and register it so we can test against it. + mozilla::dom::AutoJSAPI jsAPI; + ASSERT_TRUE(jsAPI.Init(xpc::PrivilegedJunkScope())); + JSContext* cx = jsAPI.cx(); + + mozilla::dom::GlobalObject go(cx, xpc::PrivilegedJunkScope()); + auto* wEI = new mozilla::extensions::WebExtensionInit(); + + JS::Rooted func( + cx, (JSObject*)JS_NewFunction(cx, (JSNative)1, 0, 0, "customMethodA")); + JS::Rooted tempGlobalRoot(cx, JS::CurrentGlobalOrNull(cx)); + wEI->mLocalizeCallback = new mozilla::dom::WebExtensionLocalizeCallback( + cx, func, tempGlobalRoot, nullptr); + + wEI->mAllowedOrigins = + mozilla::dom::OwningMatchPatternSetOrStringSequence(); + nsString* slotPtr = + wEI->mAllowedOrigins.SetAsStringSequence().AppendElement( + mozilla::fallible); + ASSERT_TRUE(slotPtr != nullptr); + nsString& slot = *slotPtr; + slot.Truncate(); + slot = u"http://example.com"_ns; + + wEI->mName = u"gtest Test Extension"_ns; + wEI->mId = u"gtesttestextension@mozilla.org"_ns; + wEI->mBaseURL = u"file://foo"_ns; + wEI->mMozExtensionHostname = "e37c3c08-beac-a04b-8032-c4f699a1a856"_ns; + + mozilla::ErrorResult eR; + RefPtr w = + mozilla::extensions::WebExtensionPolicy::Constructor(go, *wEI, eR); + w->SetActive(true, eR); + + constexpr auto str = + u"moz-extension://e37c3c08-beac-a04b-8032-c4f699a1a856/path/to/file.js"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, true); + + ASSERT_TRUE(ret.first == kExtensionURI && + ret.second.value() == + u"moz-extension://[gtesttestextension@mozilla.org: " + "gtest Test Extension]P=0/path/to/file.js"_ns); + + w->SetActive(false, eR); + + delete wEI; + } + { + // Set up an Extension and register it so we can test against it. + mozilla::dom::AutoJSAPI jsAPI; + ASSERT_TRUE(jsAPI.Init(xpc::PrivilegedJunkScope())); + JSContext* cx = jsAPI.cx(); + + mozilla::dom::GlobalObject go(cx, xpc::PrivilegedJunkScope()); + auto wEI = new mozilla::extensions::WebExtensionInit(); + + JS::Rooted func( + cx, (JSObject*)JS_NewFunction(cx, (JSNative)1, 0, 0, "customMethodA")); + JS::Rooted tempGlobalRoot(cx, JS::CurrentGlobalOrNull(cx)); + wEI->mLocalizeCallback = new mozilla::dom::WebExtensionLocalizeCallback( + cx, func, tempGlobalRoot, NULL); + + wEI->mAllowedOrigins = + mozilla::dom::OwningMatchPatternSetOrStringSequence(); + nsString* slotPtr = + wEI->mAllowedOrigins.SetAsStringSequence().AppendElement( + mozilla::fallible); + nsString& slot = *slotPtr; + slot.Truncate(); + slot = u"http://example.com"_ns; + + wEI->mName = u"gtest Test Extension"_ns; + wEI->mId = u"gtesttestextension@mozilla.org"_ns; + wEI->mBaseURL = u"file://foo"_ns; + wEI->mMozExtensionHostname = "e37c3c08-beac-a04b-8032-c4f699a1a856"_ns; + wEI->mIsPrivileged = true; + + mozilla::ErrorResult eR; + RefPtr w = + mozilla::extensions::WebExtensionPolicy::Constructor(go, *wEI, eR); + w->SetActive(true, eR); + + constexpr auto str = + u"moz-extension://e37c3c08-beac-a04b-8032-c4f699a1a856/path/to/file.js"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, true); + + ASSERT_TRUE(ret.first == kExtensionURI && + ret.second.value() == + u"moz-extension://[gtesttestextension@mozilla.org: " + "gtest Test Extension]P=1/path/to/file.js"_ns); + + w->SetActive(false, eR); + + delete wEI; + } + { + constexpr auto str = + u"moz-extension://e37c3c08-beac-a04b-8032-c4f699a1a856/path/to/file.js"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, false); + ASSERT_TRUE(ret.first == kExtensionURI && !ret.second.isSome()); + } + { + constexpr auto str = + u"moz-extension://e37c3c08-beac-a04b-8032-c4f699a1a856/file.js"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, true); + ASSERT_TRUE( + ret.first == kExtensionURI && + ret.second.value() == + nsLiteralString( + u"moz-extension://[failed finding addon by host]/file.js")); + } + { + constexpr auto str = + u"moz-extension://e37c3c08-beac-a04b-8032-c4f699a1a856/path/to/" + "file.js?querystringx=6"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, true); + ASSERT_TRUE(ret.first == kExtensionURI && + ret.second.value() == + u"moz-extension://[failed finding addon " + "by host]/path/to/file.js"_ns); + } +} + +TEST(FilenameEvalParser, AboutPageParser) +{ + { + constexpr auto str = u"about:about"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, false); + ASSERT_TRUE(ret.first == kAboutUri && + ret.second.value() == u"about:about"_ns); + } + { + constexpr auto str = u"about:about?hello"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, false); + ASSERT_TRUE(ret.first == kAboutUri && + ret.second.value() == u"about:about"_ns); + } + { + constexpr auto str = u"about:about#mom"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, false); + ASSERT_TRUE(ret.first == kAboutUri && + ret.second.value() == u"about:about"_ns); + } + { + constexpr auto str = u"about:about?hello=there#mom"_ns; + FilenameTypeAndDetails ret = + nsContentSecurityUtils::FilenameToFilenameType(str, false); + ASSERT_TRUE(ret.first == kAboutUri && + ret.second.value() == u"about:about"_ns); + } +} diff --git a/dom/security/test/gtest/TestSecureContext.cpp b/dom/security/test/gtest/TestSecureContext.cpp new file mode 100644 index 0000000000..dbfb4a63b6 --- /dev/null +++ b/dom/security/test/gtest/TestSecureContext.cpp @@ -0,0 +1,121 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "gtest/gtest.h" + +#include +#include + +#include "nsContentSecurityManager.h" +#include "nsContentUtils.h" +#include "nsIPrincipal.h" +#include "nsScriptSecurityManager.h" +#include "mozilla/NullPrincipal.h" +#include "mozilla/Preferences.h" + +using namespace mozilla; + +static const uint32_t kURIMaxLength = 64; + +struct TestExpectations { + char uri[kURIMaxLength]; + bool expectedResult; +}; + +class MOZ_RAII AutoRestoreBoolPref final { + public: + AutoRestoreBoolPref(const char* aPref, bool aValue) : mPref(aPref) { + Preferences::GetBool(mPref, &mOldValue); + Preferences::SetBool(mPref, aValue); + } + + ~AutoRestoreBoolPref() { Preferences::SetBool(mPref, mOldValue); } + + private: + const char* mPref = nullptr; + bool mOldValue = false; +}; + +// ============================= TestDirectives ======================== + +TEST(SecureContext, IsOriginPotentiallyTrustworthyWithContentPrincipal) +{ + // boolean isOriginPotentiallyTrustworthy(in nsIPrincipal aPrincipal); + + AutoRestoreBoolPref savedPref("network.proxy.allow_hijacking_localhost", + false); + + static const TestExpectations uris[] = { + {"http://example.com/", false}, + {"https://example.com/", true}, + {"ws://example.com/", false}, + {"wss://example.com/", true}, + {"file:///xyzzy", true}, + {"about:config", false}, + {"http://localhost", true}, + {"http://localhost.localhost", true}, + {"http://a.b.c.d.e.localhost", true}, + {"http://xyzzy.localhost", true}, + {"http://127.0.0.1", true}, + {"http://127.0.0.2", true}, + {"http://127.1.0.1", true}, + {"http://128.0.0.1", false}, + {"http://[::1]", true}, + {"http://[::ffff:127.0.0.1]", false}, + {"http://[::ffff:127.0.0.2]", false}, + {"http://[::ffff:7f00:1]", false}, + {"http://[::ffff:7f00:2]", false}, + {"resource://xyzzy", true}, + {"moz-extension://xyzzy", true}, + {"data:data:text/plain;charset=utf-8;base64,eHl6enk=", false}, + {"blob://unique-id", false}, + {"mailto:foo@bar.com", false}, + {"moz-icon://example.com", false}, + {"javascript:42", false}, + }; + + uint32_t numExpectations = sizeof(uris) / sizeof(TestExpectations); + nsCOMPtr csManager = + do_GetService(NS_CONTENTSECURITYMANAGER_CONTRACTID); + ASSERT_TRUE(!!csManager); + + nsresult rv; + for (uint32_t i = 0; i < numExpectations; i++) { + nsCOMPtr prin; + nsAutoCString uri(uris[i].uri); + rv = nsScriptSecurityManager::GetScriptSecurityManager() + ->CreateContentPrincipalFromOrigin(uri, getter_AddRefs(prin)); + ASSERT_EQ(rv, NS_OK); + bool isPotentiallyTrustworthy = prin->GetIsOriginPotentiallyTrustworthy(); + ASSERT_EQ(isPotentiallyTrustworthy, uris[i].expectedResult) + << uris[i].uri << uris[i].expectedResult; + } +} + +TEST(SecureContext, IsOriginPotentiallyTrustworthyWithSystemPrincipal) +{ + RefPtr ssManager = + nsScriptSecurityManager::GetScriptSecurityManager(); + ASSERT_TRUE(!!ssManager); + nsCOMPtr sysPrin = nsContentUtils::GetSystemPrincipal(); + bool isPotentiallyTrustworthy = sysPrin->GetIsOriginPotentiallyTrustworthy(); + ASSERT_TRUE(isPotentiallyTrustworthy); +} + +TEST(SecureContext, IsOriginPotentiallyTrustworthyWithNullPrincipal) +{ + RefPtr ssManager = + nsScriptSecurityManager::GetScriptSecurityManager(); + ASSERT_TRUE(!!ssManager); + + RefPtr nullPrin = + NullPrincipal::CreateWithoutOriginAttributes(); + bool isPotentiallyTrustworthy; + nsresult rv = + nullPrin->GetIsOriginPotentiallyTrustworthy(&isPotentiallyTrustworthy); + ASSERT_EQ(rv, NS_OK); + ASSERT_TRUE(!isPotentiallyTrustworthy); +} diff --git a/dom/security/test/gtest/TestSmartCrashTrimmer.cpp b/dom/security/test/gtest/TestSmartCrashTrimmer.cpp new file mode 100644 index 0000000000..d2238c0d75 --- /dev/null +++ b/dom/security/test/gtest/TestSmartCrashTrimmer.cpp @@ -0,0 +1,44 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "gtest/gtest.h" + +#include +#include +#include + +#include "nsContentSecurityUtils.h" +#include "nsTString.h" +#include "nsStringFwd.h" +#include "mozilla/Sprintf.h" + +#define ASSERT_STRCMP(first, second) ASSERT_TRUE(strcmp(first, second) == 0); + +#define ASSERT_STRCMP_AND_PRINT(first, second) \ + fprintf(stderr, "First: %s\n", first); \ + fprintf(stderr, "Second: %s\n", second); \ + fprintf(stderr, "strcmp = %i\n", strcmp(first, second)); \ + ASSERT_EQUAL(first, second); + +TEST(SmartCrashTrimmer, Test) +{ + static_assert(sPrintfCrashReasonSize == 1024); + { + auto ret = nsContentSecurityUtils::SmartFormatCrashString( + std::string(1025, '.').c_str()); + ASSERT_EQ(strlen(ret), 1023ul); + } + + { + auto ret = nsContentSecurityUtils::SmartFormatCrashString( + std::string(1025, '.').c_str(), std::string(1025, 'A').c_str(), + "Hello %s world %s!"); + char expected[1025]; + SprintfLiteral(expected, "Hello %s world AAAAAAAAAAAAAAAAAAAAAAAAA!", + std::string(984, '.').c_str()); + ASSERT_STRCMP(ret.get(), expected); + } +} diff --git a/dom/security/test/gtest/TestUnexpectedPrivilegedLoads.cpp b/dom/security/test/gtest/TestUnexpectedPrivilegedLoads.cpp new file mode 100644 index 0000000000..772e4bd353 --- /dev/null +++ b/dom/security/test/gtest/TestUnexpectedPrivilegedLoads.cpp @@ -0,0 +1,305 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "core/TelemetryEvent.h" +#include "gtest/gtest.h" +#include "js/Array.h" // JS::GetArrayLength +#include "js/PropertyAndElement.h" // JS_GetElement, JS_GetProperty +#include "js/TypeDecls.h" +#include "mozilla/BasePrincipal.h" +#include "mozilla/Maybe.h" +#include "mozilla/RefPtr.h" +#include "mozilla/Telemetry.h" +#include "mozilla/Unused.h" +#include "TelemetryFixture.h" +#include "TelemetryTestHelpers.h" + +#include +#include +#include "nsContentSecurityManager.h" +#include "nsContentSecurityUtils.h" +#include "nsContentUtils.h" +#include "nsIContentPolicy.h" +#include "nsILoadInfo.h" +#include "nsNetUtil.h" +#include "nsStringFwd.h" + +using namespace mozilla; +using namespace TelemetryTestHelpers; + +extern Atomic sJSHacksChecked; +extern Atomic sJSHacksPresent; +extern Atomic sCSSHacksChecked; +extern Atomic sCSSHacksPresent; + +TEST_F(TelemetryTestFixture, UnexpectedPrivilegedLoadsTelemetryTest) { + // Disable JS/CSS Hacks Detection, which would consider this current profile + // as uninteresting for our measurements: + bool origJSHacksPresent = sJSHacksPresent; + bool origJSHacksChecked = sJSHacksChecked; + sJSHacksPresent = false; + sJSHacksChecked = true; + bool origCSSHacksPresent = sCSSHacksPresent; + bool origCSSHacksChecked = sCSSHacksChecked; + sCSSHacksPresent = false; + sCSSHacksChecked = true; + + struct testResults { + nsCString fileinfo; + nsCString extraValueContenttype; + nsCString extraValueRemotetype; + nsCString extraValueFiledetails; + nsCString extraValueRedirects; + }; + + struct testCasesAndResults { + nsCString urlstring; + nsContentPolicyType contentType; + nsCString remoteType; + testResults expected; + }; + + AutoJSContextWithGlobal cx(mCleanGlobal); + // Make sure we don't look at events from other tests. + Unused << mTelemetry->ClearEvents(); + + // required for telemetry lookups + constexpr auto category = "security"_ns; + constexpr auto method = "unexpectedload"_ns; + constexpr auto object = "systemprincipal"_ns; + constexpr auto extraKeyContenttype = "contenttype"_ns; + constexpr auto extraKeyRemotetype = "remotetype"_ns; + constexpr auto extraKeyFiledetails = "filedetails"_ns; + constexpr auto extraKeyRedirects = "redirects"_ns; + + // some cases from TestFilenameEvalParser + // no need to replicate all scenarios?! + testCasesAndResults myTestCases[] = { + {"chrome://firegestures/content/browser.js"_ns, + nsContentPolicyType::TYPE_SCRIPT, + "web"_ns, + {"chromeuri"_ns, "TYPE_SCRIPT"_ns, "web"_ns, + "chrome://firegestures/content/browser.js"_ns, ""_ns}}, + {"resource://firegestures/content/browser.js"_ns, + nsContentPolicyType::TYPE_SCRIPT, + "web"_ns, + {"resourceuri"_ns, "TYPE_SCRIPT"_ns, "web"_ns, + "resource://firegestures/content/browser.js"_ns, ""_ns}}, + {// test that we don't report blob details + // ..and test that we strip of URLs from remoteTypes + "blob://000-000"_ns, + nsContentPolicyType::TYPE_SCRIPT, + "webIsolated=https://blob.example/"_ns, + {"bloburi"_ns, "TYPE_SCRIPT"_ns, "webIsolated"_ns, "unknown"_ns, ""_ns}}, + {// test for cases where finalURI is null, due to a broken nested URI + // .. like malformed moz-icon URLs + "moz-icon:blahblah"_ns, + nsContentPolicyType::TYPE_DOCUMENT, + "web"_ns, + {"other"_ns, "TYPE_DOCUMENT"_ns, "web"_ns, "unknown"_ns, ""_ns}}, + {// we dont report data urls + // ..and test that we strip of URLs from remoteTypes + "data://blahblahblah"_ns, + nsContentPolicyType::TYPE_SCRIPT, + "webCOOP+COEP=https://data.example"_ns, + {"dataurl"_ns, "TYPE_SCRIPT"_ns, "webCOOP+COEP"_ns, "unknown"_ns, + ""_ns}}, + {// handle data URLs for webextension content scripts differently + // .. by noticing their annotation + "data:text/css;extension=style;charset=utf-8,/* some css here */"_ns, + nsContentPolicyType::TYPE_STYLESHEET, + "web"_ns, + {"dataurl-extension-contentstyle"_ns, "TYPE_STYLESHEET"_ns, "web"_ns, + "unknown"_ns, ""_ns}}, + {// we only report file URLs on windows, where we can easily sanitize + "file://c/users/tom/file.txt"_ns, + nsContentPolicyType::TYPE_SCRIPT, + "web"_ns, + { +#if defined(XP_WIN) + "sanitizedWindowsURL"_ns, "TYPE_SCRIPT"_ns, "web"_ns, + "file://.../file.txt"_ns, ""_ns + +#else + "other"_ns, "TYPE_SCRIPT"_ns, "web"_ns, "unknown"_ns, ""_ns +#endif + }}, + {// test for one redirect + "moz-extension://abcdefab-1234-4321-0000-abcdefabcdef/js/assets.js"_ns, + nsContentPolicyType::TYPE_SCRIPT, + "web"_ns, + {"extension_uri"_ns, "TYPE_SCRIPT"_ns, "web"_ns, + // the extension-id is made-up, so the extension will report failure + "moz-extension://[failed finding addon by host]/js/assets.js"_ns, + "https"_ns}}, + {// test for cases where finalURI is empty + ""_ns, + nsContentPolicyType::TYPE_STYLESHEET, + "web"_ns, + {"other"_ns, "TYPE_STYLESHEET"_ns, "web"_ns, "unknown"_ns, ""_ns}}, + {// test for cases where finalURI is null, due to the struct layout, we'll + // override the URL with nullptr in loop below. + "URLWillResultInNullPtr"_ns, + nsContentPolicyType::TYPE_SCRIPT, + "web"_ns, + {"other"_ns, "TYPE_SCRIPT"_ns, "web"_ns, "unknown"_ns, ""_ns}}, + }; + + int i = 0; + for (auto const& currentTest : myTestCases) { + nsresult rv; + nsCOMPtr uri; + + // special-casing for a case where the uri is null + if (!currentTest.urlstring.Equals("URLWillResultInNullPtr")) { + NS_NewURI(getter_AddRefs(uri), currentTest.urlstring); + } + + // We can't create channels for chrome: URLs unless they are in a chrome + // registry that maps them into the actual destination URL (usually + // file://). It seems that gtest don't have chrome manifest registered, so + // we'll use a mockChannel with a mockUri. + nsCOMPtr mockUri; + rv = NS_NewURI(getter_AddRefs(mockUri), "http://example.com"_ns); + ASSERT_EQ(rv, NS_OK) << "Could not create mockUri"; + nsCOMPtr mockChannel; + nsCOMPtr service = do_GetIOService(); + if (!service) { + ASSERT_TRUE(false) + << "Couldn't initialize IOService"; + } + rv = service->NewChannelFromURI( + mockUri, nullptr, nsContentUtils::GetSystemPrincipal(), + nsContentUtils::GetSystemPrincipal(), 0, currentTest.contentType, + getter_AddRefs(mockChannel)); + ASSERT_EQ(rv, NS_OK) << "Could not create a mock channel"; + nsCOMPtr mockLoadInfo = mockChannel->LoadInfo(); + + // We're adding a redirect entry for one specific test + if (currentTest.urlstring.EqualsASCII( + "moz-extension://abcdefab-1234-4321-0000-abcdefabcdef/js/" + "assets.js")) { + nsCOMPtr redirUri; + NS_NewURI(getter_AddRefs(redirUri), + "https://www.analytics.example/analytics.js"_ns); + nsCOMPtr redirPrincipal = + BasePrincipal::CreateContentPrincipal(redirUri, OriginAttributes()); + nsCOMPtr redirectChannel; + Unused << service->NewChannelFromURI(redirUri, nullptr, redirPrincipal, + nullptr, 0, currentTest.contentType, + getter_AddRefs(redirectChannel)); + + mockLoadInfo->AppendRedirectHistoryEntry(redirectChannel, false); + } + + // this will record the event + nsContentSecurityManager::MeasureUnexpectedPrivilegedLoads( + mockLoadInfo, uri, currentTest.remoteType); + + // let's inspect the recorded events + + JS::Rooted eventsSnapshot(cx.GetJSContext()); + GetEventSnapshot(cx.GetJSContext(), &eventsSnapshot); + + ASSERT_TRUE(EventPresent(cx.GetJSContext(), eventsSnapshot, category, + method, object)) + << "Test event with value and extra must be present."; + + // Convert eventsSnapshot into array/object + JSContext* aCx = cx.GetJSContext(); + JS::Rooted arrayObj(aCx, &eventsSnapshot.toObject()); + + JS::Rooted eventRecord(aCx); + ASSERT_TRUE(JS_GetElement(aCx, arrayObj, i++, &eventRecord)) + << "Must be able to get record."; // record is already undefined :-/ + + ASSERT_TRUE(!eventRecord.isUndefined()) + << "eventRecord should not be undefined"; + + JS::Rooted recordArray(aCx, &eventRecord.toObject()); + uint32_t recordLength; + ASSERT_TRUE(JS::GetArrayLength(aCx, recordArray, &recordLength)) + << "Event record array must have length."; + ASSERT_TRUE(recordLength == 6) + << "Event record must have 6 elements."; + + JS::Rooted str(aCx); + nsAutoJSString jsStr; + // The fileinfo string is at index 4 + ASSERT_TRUE(JS_GetElement(aCx, recordArray, 4, &str)) + << "Must be able to get value."; + ASSERT_TRUE(jsStr.init(aCx, str)) + << "Value must be able to be init'd to a jsstring."; + + ASSERT_STREQ(NS_ConvertUTF16toUTF8(jsStr).get(), + currentTest.expected.fileinfo.get()) + << "Reported fileinfo '" << NS_ConvertUTF16toUTF8(jsStr).get() + << " 'equals expected value: " << currentTest.expected.fileinfo.get(); + + // Extra is at index 5 + JS::Rooted obj(aCx); + ASSERT_TRUE(JS_GetElement(aCx, recordArray, 5, &obj)) + << "Must be able to get extra data"; + JS::Rooted extraObj(aCx, &obj.toObject()); + // looking at remotetype extra for content type + JS::Rooted extraValC(aCx); + ASSERT_TRUE( + JS_GetProperty(aCx, extraObj, extraKeyContenttype.get(), &extraValC)) + << "Must be able to get the extra key's value for contenttype"; + ASSERT_TRUE(jsStr.init(aCx, extraValC)) + << "Extra value contenttype must be able to be init'd to a jsstring."; + ASSERT_STREQ(NS_ConvertUTF16toUTF8(jsStr).get(), + currentTest.expected.extraValueContenttype.get()) + << "Reported value for extra contenttype '" + << NS_ConvertUTF16toUTF8(jsStr).get() + << "' should equals supplied value" + << currentTest.expected.extraValueContenttype.get(); + // and again for remote type + JS::Rooted extraValP(aCx); + ASSERT_TRUE( + JS_GetProperty(aCx, extraObj, extraKeyRemotetype.get(), &extraValP)) + << "Must be able to get the extra key's value for remotetype"; + ASSERT_TRUE(jsStr.init(aCx, extraValP)) + << "Extra value remotetype must be able to be init'd to a jsstring."; + ASSERT_STREQ(NS_ConvertUTF16toUTF8(jsStr).get(), + currentTest.expected.extraValueRemotetype.get()) + << "Reported value for extra remotetype '" + << NS_ConvertUTF16toUTF8(jsStr).get() + << "' should equals supplied value: " + << currentTest.expected.extraValueRemotetype.get(); + // repeating the same for filedetails extra + JS::Rooted extraValF(aCx); + ASSERT_TRUE( + JS_GetProperty(aCx, extraObj, extraKeyFiledetails.get(), &extraValF)) + << "Must be able to get the extra key's value for filedetails"; + ASSERT_TRUE(jsStr.init(aCx, extraValF)) + << "Extra value filedetails must be able to be init'd to a jsstring."; + ASSERT_STREQ(NS_ConvertUTF16toUTF8(jsStr).get(), + currentTest.expected.extraValueFiledetails.get()) + << "Reported value for extra filedetails '" + << NS_ConvertUTF16toUTF8(jsStr).get() << "'should equals supplied value" + << currentTest.expected.extraValueFiledetails.get(); + // checking the extraKeyRedirects match + JS::Rooted extraValRedirects(aCx); + ASSERT_TRUE(JS_GetProperty(aCx, extraObj, extraKeyRedirects.get(), + &extraValRedirects)) + << "Must be able to get the extra value for redirects"; + ASSERT_TRUE(jsStr.init(aCx, extraValRedirects)) + << "Extra value redirects must be able to be init'd to a jsstring"; + ASSERT_STREQ(NS_ConvertUTF16toUTF8(jsStr).get(), + currentTest.expected.extraValueRedirects.get()) + << "Reported value for extra redirect '" + << NS_ConvertUTF16toUTF8(jsStr).get() + << "' should equals supplied value: " + << currentTest.expected.extraValueRedirects.get(); + } + + // Re-store JS/CSS hacks detection state + sJSHacksPresent = origJSHacksPresent; + sJSHacksChecked = origJSHacksChecked; + sCSSHacksPresent = origCSSHacksPresent; + sCSSHacksChecked = origCSSHacksChecked; +} diff --git a/dom/security/test/gtest/moz.build b/dom/security/test/gtest/moz.build new file mode 100644 index 0000000000..c9ab4dcece --- /dev/null +++ b/dom/security/test/gtest/moz.build @@ -0,0 +1,25 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +UNIFIED_SOURCES += [ + "TestCSPParser.cpp", + "TestFilenameEvalParser.cpp", + "TestSecureContext.cpp", + "TestSmartCrashTrimmer.cpp", +] + +if CONFIG["OS_TARGET"] != "Android": + UNIFIED_SOURCES += [ + "TestUnexpectedPrivilegedLoads.cpp", + ] + +FINAL_LIBRARY = "xul-gtest" + +LOCAL_INCLUDES += [ + "/caps", + "/toolkit/components/telemetry/", + "/toolkit/components/telemetry/tests/gtest", +] diff --git a/dom/security/test/https-first/browser.toml b/dom/security/test/https-first/browser.toml new file mode 100644 index 0000000000..0c63b8317d --- /dev/null +++ b/dom/security/test/https-first/browser.toml @@ -0,0 +1,53 @@ +[DEFAULT] + +["browser_beforeunload_permit_http.js"] +support-files = ["file_beforeunload_permit_http.html"] + +["browser_downgrade_mixed_content_auto_upgrade_console.js"] +support-files = [ + "file_mixed_content_auto_upgrade.html", + "pass.png", + "test.ogv", + "test.wav", +] + +["browser_downgrade_view_source.js"] +support-files = ["file_downgrade_view_source.sjs"] + +["browser_download_attribute.js"] +support-files = [ + "file_download_attribute.html", + "file_download_attribute.sjs", +] + +["browser_httpsfirst.js"] +support-files = ["file_httpsfirst_timeout_server.sjs"] + +["browser_httpsfirst_console_logging.js"] + +["browser_httpsfirst_speculative_connect.js"] +support-files = ["file_httpsfirst_speculative_connect.html"] + +["browser_mixed_content_console.js"] +support-files = ["file_mixed_content_console.html"] + +["browser_mixed_content_download.js"] +support-files = [ + "download_page.html", + "download_server.sjs", +] + +["browser_navigation.js"] +support-files = ["file_navigation.html"] + +["browser_schemeless.js"] + +["browser_slow_download.js"] +support-files = [ + "file_slow_download.html", + "file_slow_download.sjs", +] + +["browser_superfluos_auth.js"] + +["browser_upgrade_onion.js"] diff --git a/dom/security/test/https-first/browser_beforeunload_permit_http.js b/dom/security/test/https-first/browser_beforeunload_permit_http.js new file mode 100644 index 0000000000..660c1a352d --- /dev/null +++ b/dom/security/test/https-first/browser_beforeunload_permit_http.js @@ -0,0 +1,208 @@ +"use strict"; + +const { PromptTestUtils } = ChromeUtils.importESModule( + "resource://testing-common/PromptTestUtils.sys.mjs" +); + +const TEST_PATH_HTTP = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + // eslint-disable-next-line @microsoft/sdl/no-insecure-url + "http://nocert.example.com/" +); +/* + * Description of Tests: + * + * Test load page and reload: + * 1. Enable HTTPS-First and the pref to trigger beforeunload by user interaction + * 2. Open an HTTP site. HTTPS-First will try to upgrade it to https - but since it has no cert that try will fail + * 3. Then simulated user interaction and reload the page with a reload flag. + * 4. That should lead to a beforeUnload prompt that asks for users permission to perform reload. HTTPS-First should not try to upgrade the reload again + * + * Test Navigation: + * 1. Enable HTTPS-First and the pref to trigger beforeunload by user interaction + * 2. Open an http site. HTTPS-First will try to upgrade it to https - but since it has no cert for https that try will fail + * 3. Then simulated user interaction and navigate to another http page. Again HTTPS-First will try to upgrade to HTTPS + * 4. This attempted navigation leads to a prompt which askes for permission to leave page - accept it + * 5. Since the site is not using a valid HTTPS cert HTTPS-First will downgrade the request back to HTTP + * 6. User should NOT get asked again for permission to unload + * + * Test Session History Navigation: + * 1. Enable HTTPS-First and the pref to trigger beforeunload by user interaction + * 2. Open an http site. HTTPS-First will try to upgrade it to https - but since it has no cert for https that try will fail + * 3. Then navigate to another http page and simulated a user interaction. + * 4. Trigger a session history navigation by clicking the "back button". + * 5. This attempted navigation leads to a prompt which askes for permission to leave page - accept it + */ +add_setup(async function () { + await SpecialPowers.pushPrefEnv({ + set: [ + ["dom.security.https_first", true], + ["dom.require_user_interaction_for_beforeunload", true], + ], + }); +}); +const TESTS = [ + { + name: "Normal Reload (No flag)", + reloadFlag: Ci.nsIWebNavigation.LOAD_FLAGS_NONE, + }, + { + name: "Bypass Cache Reload", + reloadFlag: Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE, + }, + { + name: "Bypass Proxy Reload", + reloadFlag: Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_PROXY, + }, + { + name: "Bypass Cache and Proxy Reload", + reloadFlag: + Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE | + Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_PROXY, + }, +]; + +add_task(async function testReloadFlags() { + for (let index = 0; index < TESTS.length; index++) { + const testCase = TESTS[index]; + // The onbeforeunload dialog should appear + let dialogPromise = PromptTestUtils.waitForPrompt(null, { + modalType: Services.prompt.MODAL_TYPE_CONTENT, + promptType: "confirmEx", + }); + let reloadPromise = loadPageAndReload(testCase); + let dialog = await dialogPromise; + Assert.ok(true, "Showed the beforeunload dialog."); + await PromptTestUtils.handlePrompt(dialog, { buttonNumClick: 0 }); + await reloadPromise; + } +}); + +add_task(async function testNavigation() { + // The onbeforeunload dialog should appear + let dialogPromise = PromptTestUtils.waitForPrompt(null, { + modalType: Services.prompt.MODAL_TYPE_CONTENT, + promptType: "confirmEx", + }); + + let openPagePromise = openPage(); + let dialog = await dialogPromise; + Assert.ok(true, "Showed the beforeunload dialog."); + await PromptTestUtils.handlePrompt(dialog, { buttonNumClick: 0 }); + await openPagePromise; +}); + +add_task(async function testSessionHistoryNavigation() { + // The onbeforeunload dialog should appear + let dialogPromise = PromptTestUtils.waitForPrompt(null, { + modalType: Services.prompt.MODAL_TYPE_CONTENT, + promptType: "confirmEx", + }); + + let openPagePromise = loadPagesAndUseBackButton(); + let dialog = await dialogPromise; + Assert.ok(true, "Showed the beforeunload dialog."); + await PromptTestUtils.handlePrompt(dialog, { buttonNumClick: 0 }); + await openPagePromise; +}); + +async function openPage() { + // Open about:blank in a new tab + await BrowserTestUtils.withNewTab( + { gBrowser, url: "about:blank" }, + async function (browser) { + // Load http page + BrowserTestUtils.startLoadingURIString( + browser, + `${TEST_PATH_HTTP}file_beforeunload_permit_http.html` + ); + await BrowserTestUtils.browserLoaded(browser); + // Interact with page such that unload permit will be necessary + await BrowserTestUtils.synthesizeMouse("body", 2, 2, {}, browser); + let hasInteractedWith = await SpecialPowers.spawn( + browser, + [""], + function () { + return content.document.userHasInteracted; + } + ); + + is(true, hasInteractedWith, "Simulated successfully user interaction"); + // And then navigate away to another site which proves that user won't be asked twice to permit a reload (otherwise the test get timed out) + BrowserTestUtils.startLoadingURIString( + browser, + // eslint-disable-next-line @microsoft/sdl/no-insecure-url + "http://self-signed.example.com/" + ); + await BrowserTestUtils.browserLoaded(browser); + Assert.ok(true, "Navigated successfully."); + } + ); +} + +async function loadPageAndReload(testCase) { + // Load initial site + // Open about:blank in a new tab + await BrowserTestUtils.withNewTab( + { gBrowser, url: "about:blank" }, + async function (browser) { + BrowserTestUtils.startLoadingURIString( + browser, + `${TEST_PATH_HTTP}file_beforeunload_permit_http.html` + ); + await BrowserTestUtils.browserLoaded(browser); + // Interact with page such that unload permit will be necessary + await BrowserTestUtils.synthesizeMouse("body", 2, 2, {}, browser); + + let hasInteractedWith = await SpecialPowers.spawn( + browser, + [""], + function () { + return content.document.userHasInteracted; + } + ); + is(true, hasInteractedWith, "Simulated successfully user interaction"); + BrowserReloadWithFlags(testCase.reloadFlag); + await BrowserTestUtils.browserLoaded(browser); + is(true, true, `reload with flag ${testCase.name} was successful`); + } + ); +} + +async function loadPagesAndUseBackButton() { + // Load initial site + // Open about:blank in a new tab + await BrowserTestUtils.withNewTab( + { gBrowser, url: "about:blank" }, + async function (browser) { + BrowserTestUtils.startLoadingURIString( + browser, + `${TEST_PATH_HTTP}file_beforeunload_permit_http.html` + ); + await BrowserTestUtils.browserLoaded(browser); + + BrowserTestUtils.startLoadingURIString( + browser, + `${TEST_PATH_HTTP}file_beforeunload_permit_http.html?getASessionHistoryEntry` + ); + await BrowserTestUtils.browserLoaded(browser); + // Interact with page such that unload permit will be necessary + await BrowserTestUtils.synthesizeMouse("body", 2, 2, {}, browser); + + let hasInteractedWith = await SpecialPowers.spawn( + browser, + [""], + function () { + return content.document.userHasInteracted; + } + ); + is(true, hasInteractedWith, "Simulated successfully user interaction"); + // Go back one site by clicking the back button + info("Clicking back button"); + let backButton = document.getElementById("back-button"); + backButton.click(); + await BrowserTestUtils.browserLoaded(browser); + is(true, true, `Got back successful`); + } + ); +} diff --git a/dom/security/test/https-first/browser_downgrade_mixed_content_auto_upgrade_console.js b/dom/security/test/https-first/browser_downgrade_mixed_content_auto_upgrade_console.js new file mode 100644 index 0000000000..8f1778135a --- /dev/null +++ b/dom/security/test/https-first/browser_downgrade_mixed_content_auto_upgrade_console.js @@ -0,0 +1,82 @@ +// Bug 1673574 - Improve Console logging for mixed content auto upgrading +"use strict"; + +const testPath = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "http://httpsfirst.com" +); + +let tests = [ + { + description: "Top-Level upgrade should get logged", + expectLogLevel: Ci.nsIConsoleMessage.warn, + expectIncludes: ["Upgrading insecure request", "to use", "httpsfirst.com"], + }, + { + description: "Top-Level upgrade failure should get logged", + expectLogLevel: Ci.nsIConsoleMessage.warn, + expectIncludes: [ + "Upgrading insecure request", + "failed", + "httpsfirst.com", + "Downgrading to", + ], + }, +]; + +const kTestURI = testPath + "file_mixed_content_auto_upgrade.html"; + +add_task(async function () { + // A longer timeout is necessary for this test than the plain mochitests + // due to opening a new tab with the web console. + requestLongerTimeout(4); + + // Enable ML2 and HTTPS-First Mode and register console-listener + await SpecialPowers.pushPrefEnv({ + set: [ + ["security.mixed_content.upgrade_display_content", true], + ["dom.security.https_first", true], + ], + }); + Services.console.registerListener(on_new_message); + // 1. Upgrade page to https:// + let promiseLoaded = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser); + BrowserTestUtils.startLoadingURIString(gBrowser.selectedBrowser, kTestURI); + await promiseLoaded; + + await BrowserTestUtils.waitForCondition(() => tests.length === 0); + + // Clean up + Services.console.unregisterListener(on_new_message); +}); + +function on_new_message(msgObj) { + const message = msgObj.message; + const logLevel = msgObj.logLevel; + + // The console message is: + // Should only show HTTPS-First messages + + if (message.includes("Mixed Content:")) { + ok( + !message.includes("Upgrading insecure display request"), + "msg included a mixed content upgrade" + ); + } + if (message.includes("HTTPS-First Mode:")) { + for (let i = 0; i < tests.length; i++) { + const testCase = tests[i]; + // Check if log-level matches + if (logLevel !== testCase.expectLogLevel) { + continue; + } + // Check if all substrings are included + if (testCase.expectIncludes.some(str => !message.includes(str))) { + continue; + } + ok(true, testCase.description); + tests.splice(i, 1); + break; + } + } +} diff --git a/dom/security/test/https-first/browser_downgrade_view_source.js b/dom/security/test/https-first/browser_downgrade_view_source.js new file mode 100644 index 0000000000..3d5552c79f --- /dev/null +++ b/dom/security/test/https-first/browser_downgrade_view_source.js @@ -0,0 +1,81 @@ +// This test ensures that view-source:https falls back to view-source:http +"use strict"; + +const TEST_PATH_HTTP = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "http://example.com" +); + +const TEST_PATH_HTTPS = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "https://example.com" +); + +async function runTest(desc, url, expectedURI, excpectedContent) { + await BrowserTestUtils.withNewTab("about:blank", async function (browser) { + let loaded = BrowserTestUtils.browserLoaded(browser, false, null, true); + BrowserTestUtils.startLoadingURIString(browser, url); + await loaded; + + await SpecialPowers.spawn( + browser, + [desc, expectedURI, excpectedContent], + async function (desc, expectedURI, excpectedContent) { + let loadedURI = content.document.documentURI; + is(loadedURI, expectedURI, desc); + let loadedContent = content.document.body.textContent; + is(loadedContent, excpectedContent, desc); + } + ); + }); +} + +add_task(async function () { + requestLongerTimeout(2); + + await SpecialPowers.pushPrefEnv({ + set: [["dom.security.https_first", true]], + }); + + await runTest( + "URL with query 'downgrade' should be http:", + `view-source:${TEST_PATH_HTTP}/file_downgrade_view_source.sjs?downgrade`, + `view-source:${TEST_PATH_HTTP}/file_downgrade_view_source.sjs?downgrade`, + "view-source:http://" + ); + + await runTest( + "URL with query 'downgrade' should be http and leave query params untouched:", + `view-source:${TEST_PATH_HTTP}/file_downgrade_view_source.sjs?downgrade&https://httpsfirst.com`, + `view-source:${TEST_PATH_HTTP}/file_downgrade_view_source.sjs?downgrade&https://httpsfirst.com`, + "view-source:http://" + ); + + await runTest( + "URL with query 'upgrade' should be https:", + `view-source:${TEST_PATH_HTTP}/file_downgrade_view_source.sjs?upgrade`, + `view-source:${TEST_PATH_HTTPS}/file_downgrade_view_source.sjs?upgrade`, + "view-source:https://" + ); + + await runTest( + "URL with query 'upgrade' should be https:", + `view-source:${TEST_PATH_HTTPS}/file_downgrade_view_source.sjs?upgrade`, + `view-source:${TEST_PATH_HTTPS}/file_downgrade_view_source.sjs?upgrade`, + "view-source:https://" + ); + + await runTest( + "URL with query 'upgrade' should be https and leave query params untouched:", + `view-source:${TEST_PATH_HTTP}/file_downgrade_view_source.sjs?upgrade&https://httpsfirst.com`, + `view-source:${TEST_PATH_HTTPS}/file_downgrade_view_source.sjs?upgrade&https://httpsfirst.com`, + "view-source:https://" + ); + + await runTest( + "URL with query 'upgrade' should be https and leave query params untouched:", + `view-source:${TEST_PATH_HTTPS}/file_downgrade_view_source.sjs?upgrade&https://httpsfirst.com`, + `view-source:${TEST_PATH_HTTPS}/file_downgrade_view_source.sjs?upgrade&https://httpsfirst.com`, + "view-source:https://" + ); +}); diff --git a/dom/security/test/https-first/browser_download_attribute.js b/dom/security/test/https-first/browser_download_attribute.js new file mode 100644 index 0000000000..8165add998 --- /dev/null +++ b/dom/security/test/https-first/browser_download_attribute.js @@ -0,0 +1,125 @@ +"use strict"; + +// Create a uri for an http site +//(in that case a site without cert such that https-first isn't upgrading it) +const insecureTestPath = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "http://nocert.example.com" +); +const insecureTestURI = insecureTestPath + "file_download_attribute.html"; + +function promisePanelOpened() { + if (DownloadsPanel.panel && DownloadsPanel.panel.state == "open") { + return Promise.resolve(); + } + return BrowserTestUtils.waitForEvent(DownloadsPanel.panel, "popupshown"); +} + +const CONSOLE_UPGRADE_TRY_MESSAGE = "Upgrading insecure request"; +const CONSOLE_ERROR_MESSAGE = "Downgrading to “http” again"; +const DOWNLOAD_PAGE_URL = + "nocert.example.com/browser/dom/security/test/https-first/file_download_attribute.html"; +const DOWNLOAD_LINK_URL = + "nocert.example.com/browser/dom/security/test/https-first/file_download_attribute.sjs"; + +// Verifys that https-first tried to upgrade the download +// - and that the upgrade attempt failed. +// We will receive 4 messages. Two for upgrading and downgrading +// the download page and another two for upgrading and downgrading +// the download. +let msgCounter = 0; +function shouldConsoleTryUpgradeAndError() { + // Waits until CONSOLE_ERROR_MESSAGE was logged. + // Checks if download was tried via http:// + return new Promise((resolve, reject) => { + function listener(msgObj) { + let text = msgObj.message; + // Verify upgrade messages + if ( + text.includes(CONSOLE_UPGRADE_TRY_MESSAGE) && + text.includes("http://") + ) { + if (msgCounter == 0) { + ok( + text.includes(DOWNLOAD_PAGE_URL), + "Tries to upgrade nocert example to https" + ); + } else { + ok( + text.includes(DOWNLOAD_LINK_URL), + "Tries to upgrade download to https" + ); + } + msgCounter++; + } + // Verify downgrade messages + if (text.includes(CONSOLE_ERROR_MESSAGE) && msgCounter > 0) { + if (msgCounter == 1) { + ok( + text.includes("https://" + DOWNLOAD_PAGE_URL), + "Downgrades nocert example to http" + ); + msgCounter++; + } else { + ok( + text.includes("https://" + DOWNLOAD_LINK_URL), + "Downgrades download to http" + ); + Services.console.unregisterListener(listener); + resolve(); + } + } + } + Services.console.registerListener(listener); + }); +} + +// Test https-first download of an html file from an http site. +// Test description: +// 1. https-first tries to upgrade site to https +// 2. upgrade fails because site has no certificate +// 3. https-first downgrades to http and starts download via http +// 4. Successfully completes download +add_task(async function test_with_downloads_pref_enabled() { + await SpecialPowers.pushPrefEnv({ + set: [["dom.security.https_first", true]], + }); + let checkPromise = shouldConsoleTryUpgradeAndError(); + let downloadsPanelPromise = promisePanelOpened(); + let downloadsPromise = Downloads.getList(Downloads.PUBLIC); + + BrowserTestUtils.startLoadingURIString(gBrowser, insecureTestURI); + // wait for downloadsPanel to open before continuing with test + await downloadsPanelPromise; + let downloadList = await downloadsPromise; + await checkPromise; + is(DownloadsPanel.isPanelShowing, true, "DownloadsPanel should be open."); + is( + downloadList._downloads.length, + 1, + "File should be successfully downloaded." + ); + + let [download] = downloadList._downloads; + is(download.contentType, "text/html", "File contentType should be correct."); + // ensure https-first didn't upgrade the scheme. + is( + download.source.url, + insecureTestPath + "file_download_attribute.sjs", + "Scheme should be http." + ); + + info("cleaning up downloads"); + try { + if (Services.appinfo.OS === "WINNT") { + // We need to make the file writable to delete it on Windows. + await IOUtils.setPermissions(download.target.path, 0o600); + } + await IOUtils.remove(download.target.path); + } catch (error) { + info("The file " + download.target.path + " is not removed, " + error); + } + + await downloadList.remove(download); + await download.finalize(); +}); diff --git a/dom/security/test/https-first/browser_httpsfirst.js b/dom/security/test/https-first/browser_httpsfirst.js new file mode 100644 index 0000000000..733474dcc1 --- /dev/null +++ b/dom/security/test/https-first/browser_httpsfirst.js @@ -0,0 +1,74 @@ +"use strict"; + +const TEST_PATH_HTTP = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "http://example.com" +); + +const TIMEOUT_PAGE_URI_HTTP = + TEST_PATH_HTTP + "file_httpsfirst_timeout_server.sjs"; + +async function runPrefTest(aURI, aDesc, aAssertURLStartsWith) { + await BrowserTestUtils.withNewTab("about:blank", async function (browser) { + const loaded = BrowserTestUtils.browserLoaded(browser, false, null, true); + BrowserTestUtils.startLoadingURIString(browser, aURI); + await loaded; + + await ContentTask.spawn( + browser, + { aDesc, aAssertURLStartsWith }, + function ({ aDesc, aAssertURLStartsWith }) { + ok( + content.document.location.href.startsWith(aAssertURLStartsWith), + aDesc + ); + } + ); + }); +} + +add_task(async function () { + await SpecialPowers.pushPrefEnv({ + set: [["dom.security.https_first", false]], + }); + + await runPrefTest( + "http://example.com", + "HTTPS-First disabled; Should not upgrade", + "http://" + ); + + await SpecialPowers.pushPrefEnv({ + set: [["dom.security.https_first", true]], + }); + + await runPrefTest( + "http://example.com", + "Should upgrade upgradeable website", + "https://" + ); + + await runPrefTest( + "http://httpsfirst.com", + "Should downgrade after error.", + "http://" + ); + + await runPrefTest( + "http://httpsfirst.com/?https://httpsfirst.com", + "Should downgrade after error and leave query params untouched.", + "http://httpsfirst.com/?https://httpsfirst.com" + ); + + await runPrefTest( + "http://domain.does.not.exist", + "Should not downgrade on dnsNotFound error.", + "https://" + ); + + await runPrefTest( + TIMEOUT_PAGE_URI_HTTP, + "Should downgrade after timeout.", + "http://" + ); +}); diff --git a/dom/security/test/https-first/browser_httpsfirst_console_logging.js b/dom/security/test/https-first/browser_httpsfirst_console_logging.js new file mode 100644 index 0000000000..84a2cbbcbc --- /dev/null +++ b/dom/security/test/https-first/browser_httpsfirst_console_logging.js @@ -0,0 +1,72 @@ +// Bug 1658924 - HTTPS-First Mode - Tests for console logging +// https://bugzilla.mozilla.org/show_bug.cgi?id=1658924 +// This test makes sure that the various console messages from the HTTPS-First +// mode get logged to the console. +"use strict"; + +// Test Cases +// description: Description of what the subtests expects. +// expectLogLevel: Expected log-level of a message. +// expectIncludes: Expected substrings the message should contain. +let tests = [ + { + description: "Top-Level upgrade should get logged", + expectLogLevel: Ci.nsIConsoleMessage.warn, + expectIncludes: ["Upgrading insecure request", "to use", "httpsfirst.com"], + }, + { + description: "Top-Level upgrade failure should get logged", + expectLogLevel: Ci.nsIConsoleMessage.warn, + expectIncludes: [ + "Upgrading insecure request", + "failed", + "httpsfirst.com", + "Downgrading to", + ], + }, +]; + +add_task(async function () { + // A longer timeout is necessary for this test than the plain mochitests + // due to opening a new tab with the web console. + requestLongerTimeout(4); + + // Enable HTTPS-First Mode and register console-listener + await SpecialPowers.pushPrefEnv({ + set: [["dom.security.https_first", true]], + }); + Services.console.registerListener(on_new_message); + // 1. Upgrade page to https:// + let promiseLoaded = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser); + BrowserTestUtils.startLoadingURIString( + gBrowser.selectedBrowser, + "http://httpsfirst.com" + ); + await promiseLoaded; + await BrowserTestUtils.waitForCondition(() => tests.length === 0); + + // Clean up + Services.console.unregisterListener(on_new_message); +}); + +function on_new_message(msgObj) { + const message = msgObj.message; + const logLevel = msgObj.logLevel; + + if (message.includes("HTTPS-First Mode:")) { + for (let i = 0; i < tests.length; i++) { + const testCase = tests[i]; + // Check if log-level matches + if (logLevel !== testCase.expectLogLevel) { + continue; + } + // Check if all substrings are included + if (testCase.expectIncludes.some(str => !message.includes(str))) { + continue; + } + ok(true, testCase.description); + tests.splice(i, 1); + break; + } + } +} diff --git a/dom/security/test/https-first/browser_httpsfirst_speculative_connect.js b/dom/security/test/https-first/browser_httpsfirst_speculative_connect.js new file mode 100644 index 0000000000..f06ba0a944 --- /dev/null +++ b/dom/security/test/https-first/browser_httpsfirst_speculative_connect.js @@ -0,0 +1,71 @@ +"use strict"; + +const TEST_PATH_HTTP = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "http://example.com" +); + +let console_messages = [ + { + description: "Speculative Connection should get logged", + expectLogLevel: Ci.nsIConsoleMessage.warn, + expectIncludes: [ + "Upgrading insecure speculative TCP connection", + "to use", + "example.com", + "file_httpsfirst_speculative_connect.html", + ], + }, + { + description: "Upgrade should get logged", + expectLogLevel: Ci.nsIConsoleMessage.warn, + expectIncludes: [ + "Upgrading insecure request", + "to use", + "example.com", + "file_httpsfirst_speculative_connect.html", + ], + }, +]; + +function on_new_console_messages(msgObj) { + const message = msgObj.message; + const logLevel = msgObj.logLevel; + + if (message.includes("HTTPS-First Mode:")) { + for (let i = 0; i < console_messages.length; i++) { + const testCase = console_messages[i]; + // Check if log-level matches + if (logLevel !== testCase.expectLogLevel) { + continue; + } + // Check if all substrings are included + if (testCase.expectIncludes.some(str => !message.includes(str))) { + continue; + } + ok(true, testCase.description); + console_messages.splice(i, 1); + break; + } + } +} + +add_task(async function () { + requestLongerTimeout(4); + + await SpecialPowers.pushPrefEnv({ + set: [["dom.security.https_first", true]], + }); + Services.console.registerListener(on_new_console_messages); + + let promiseLoaded = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser); + BrowserTestUtils.startLoadingURIString( + gBrowser.selectedBrowser, + `${TEST_PATH_HTTP}file_httpsfirst_speculative_connect.html` + ); + await promiseLoaded; + + await BrowserTestUtils.waitForCondition(() => console_messages.length === 0); + + Services.console.unregisterListener(on_new_console_messages); +}); diff --git a/dom/security/test/https-first/browser_mixed_content_console.js b/dom/security/test/https-first/browser_mixed_content_console.js new file mode 100644 index 0000000000..c8322c036f --- /dev/null +++ b/dom/security/test/https-first/browser_mixed_content_console.js @@ -0,0 +1,104 @@ +// Bug 1713593: HTTPS-First: Add test for mixed content blocker. +"use strict"; + +const testPath = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "http://example.com" +); + +const UPGRADE_DISPLAY_CONTENT = + "security.mixed_content.upgrade_display_content"; + +let threeMessagesArrived = 0; +let messageImageSeen = false; + +const kTestURI = testPath + "file_mixed_content_console.html"; + +add_task(async function () { + // A longer timeout is necessary for this test than the plain mochitests + // due to opening a new tab with the web console. + requestLongerTimeout(4); + + // Enable HTTPS-First Mode and register console-listener + await SpecialPowers.pushPrefEnv({ + set: [["dom.security.https_first", true]], + }); + Services.console.registerListener(on_console_message); + BrowserTestUtils.startLoadingURIString(gBrowser.selectedBrowser, kTestURI); + + await BrowserTestUtils.waitForCondition(() => threeMessagesArrived === 3); + + Services.console.unregisterListener(on_console_message); +}); + +function on_console_message(msgObj) { + const message = msgObj.message; + + // The first console message is: + // "HTTPS-First Mode: Upgrading insecure request + // ‘http://example.com/browser/dom/security/test/https-first/file_mixed_content_console.html’ to use ‘https’" + if (message.includes("HTTPS-First Mode: Upgrading insecure request")) { + ok(message.includes("Upgrading insecure request"), "request got upgraded"); + ok( + message.includes( + "“http://example.com/browser/dom/security/test/https-first/file_mixed_content_console.html” to use “https”." + ), + "correct top-level request" + ); + threeMessagesArrived++; + } + // If security.mixed_content.upgrade_display_content is enabled: + // The second console message is about upgrading the insecure image + else if ( + Services.prefs.getBoolPref(UPGRADE_DISPLAY_CONTENT) && + message.includes("Mixed Content: Upgrading") + ) { + ok( + message.includes("insecure display request"), + "display content got load" + ); + ok( + message.includes( + "‘http://example.com/browser/dom/security/test/https-first/auto_upgrading_identity.png’ to use ‘https’" + ), + "img loaded secure" + ); + threeMessagesArrived++; + messageImageSeen = true; + } + // Else: + // The second console message is about blocking the image: + // Message: "Loading mixed (insecure) display content + // “http://example.com/browser/dom/security/test/https-first/auto_upgrading_identity.png” on a secure page". + // Since the message is send twice, prevent reading the image message two times + else if (message.includes("Loading mixed") && !messageImageSeen) { + ok( + message.includes("Loading mixed (insecure) display content"), + "display content got load" + ); + ok( + message.includes( + "“http://example.com/browser/dom/security/test/https-first/auto_upgrading_identity.png” on a secure page" + ), + "img loaded insecure" + ); + threeMessagesArrived++; + messageImageSeen = true; + } + // The third message is: + // "Blocked loading mixed active content + // "http://example.com/browser/dom/security/test/https-first/barfoo"" + else if (message.includes("Blocked loading")) { + ok( + message.includes("Blocked loading mixed active content"), + "script got blocked" + ); + ok( + message.includes( + "http://example.com/browser/dom/security/test/https-first/barfoo" + ), + "the right script got blocked" + ); + threeMessagesArrived++; + } +} diff --git a/dom/security/test/https-first/browser_mixed_content_download.js b/dom/security/test/https-first/browser_mixed_content_download.js new file mode 100644 index 0000000000..09ea64cea8 --- /dev/null +++ b/dom/security/test/https-first/browser_mixed_content_download.js @@ -0,0 +1,156 @@ +ChromeUtils.defineESModuleGetters(this, { + Downloads: "resource://gre/modules/Downloads.sys.mjs", + DownloadsCommon: "resource:///modules/DownloadsCommon.sys.mjs", +}); + +const HandlerService = Cc[ + "@mozilla.org/uriloader/handler-service;1" +].getService(Ci.nsIHandlerService); + +const MIMEService = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService); + +let SECURE_BASE_URL = + getRootDirectory(gTestPath).replace( + "chrome://mochitests/content/", + "https://example.com/" + ) + "download_page.html"; + +/** + * Waits until a download is triggered. + * It waits until a prompt is shown, + * saves and then accepts the dialog. + * @returns {Promise} Resolved once done. + */ + +function shouldTriggerDownload() { + return new Promise((resolve, reject) => { + Services.wm.addListener({ + onOpenWindow(xulWin) { + Services.wm.removeListener(this); + let win = xulWin.docShell.domWindow; + waitForFocus(() => { + if ( + win.location == + "chrome://mozapps/content/downloads/unknownContentType.xhtml" + ) { + let dialog = win.document.getElementById("unknownContentType"); + let button = dialog.getButton("accept"); + let actionRadio = win.document.getElementById("save"); + actionRadio.click(); + button.disabled = false; + dialog.acceptDialog(); + resolve(); + } else { + reject(); + } + }, win); + }, + }); + }); +} + +const CONSOLE_UPGRADE_MESSAGE = "Upgrading insecure request"; +const CONSOLE_DOWNGRADE_MESSAGE = "Downgrading to “http” again."; +const DOWNLOAD_URL = + "example.com/browser/dom/security/test/https-first/download_server.sjs"; +// Verifies that https-first tries to upgrade download, +// falls back since download is not available via https +let msgCounter = 0; +function shouldConsoleError() { + return new Promise((resolve, reject) => { + function listener(msgObj) { + let text = msgObj.message; + if (text.includes(CONSOLE_UPGRADE_MESSAGE) && msgCounter == 0) { + ok( + text.includes("http://" + DOWNLOAD_URL), + "Https-first tries to upgrade download to https" + ); + msgCounter++; + } + if (text.includes(CONSOLE_DOWNGRADE_MESSAGE) && msgCounter == 1) { + ok( + text.includes("https://" + DOWNLOAD_URL), + "Https-first downgrades download to http." + ); + resolve(); + Services.console.unregisterListener(listener); + } + } + Services.console.registerListener(listener); + }); +} + +async function resetDownloads() { + // Removes all downloads from the download List + const types = new Set(); + let publicList = await Downloads.getList(Downloads.PUBLIC); + let downloads = await publicList.getAll(); + for (let download of downloads) { + if (download.contentType) { + types.add(download.contentType); + } + publicList.remove(download); + await download.finalize(true); + } + + if (types.size) { + // reset handlers for the contentTypes of any files previously downloaded + for (let type of types) { + const mimeInfo = MIMEService.getFromTypeAndExtension(type, ""); + info("resetting handler for type: " + type); + HandlerService.remove(mimeInfo); + } + } +} + +async function runTest(url, link, checkFunction, description) { + await SpecialPowers.pushPrefEnv({ + set: [ + ["dom.security.https_first", true], + ["browser.download.always_ask_before_handling_new_types", true], + ], + }); + requestLongerTimeout(2); + await resetDownloads(); + + let tab = BrowserTestUtils.addTab(gBrowser, url); + gBrowser.selectedTab = tab; + + let browser = gBrowser.getBrowserForTab(tab); + await BrowserTestUtils.browserLoaded(browser); + is( + gBrowser.currentURI.schemeIs("https"), + true, + "Scheme of opened tab should be https" + ); + info("Checking: " + description); + + let checkPromise = checkFunction(); + // Click the Link to trigger the download + SpecialPowers.spawn(gBrowser.selectedBrowser, [link], contentLink => { + content.document.getElementById(contentLink).click(); + }); + await checkPromise; + ok(true, description); + BrowserTestUtils.removeTab(tab); +} + +//Test description: +// 1. Open "https://example.com" +// 2. From "https://example.com" download something, but that download is only available via http. +// 3. Https-first tries to upgrade the download. +// 4. Upgrading fails - so http-first downgrade download to http. + +add_task(async function test_mixed_download() { + await runTest( + SECURE_BASE_URL, + "insecure", + () => Promise.all([shouldTriggerDownload(), shouldConsoleError()]), + "Secure -> Insecure should Error" + ); + // remove downloaded file + let downloadsPromise = Downloads.getList(Downloads.PUBLIC); + let downloadList = await downloadsPromise; + let [download] = downloadList._downloads; + await downloadList.remove(download); +}); diff --git a/dom/security/test/https-first/browser_navigation.js b/dom/security/test/https-first/browser_navigation.js new file mode 100644 index 0000000000..dba83d5645 --- /dev/null +++ b/dom/security/test/https-first/browser_navigation.js @@ -0,0 +1,97 @@ +"use strict"; + +const REQUEST_URL = + "http://httpsfirst.com/browser/dom/security/test/https-first/"; + +async function promiseGetHistoryIndex(browser) { + if (!SpecialPowers.Services.appinfo.sessionHistoryInParent) { + return SpecialPowers.spawn(browser, [], function () { + let shistory = + docShell.browsingContext.childSessionHistory.legacySHistory; + return shistory.index; + }); + } + + let shistory = browser.browsingContext.sessionHistory; + return shistory.index; +} + +async function testNavigations() { + // Load initial site + + let url1 = REQUEST_URL + "file_navigation.html?foo1"; + let url2 = REQUEST_URL + "file_navigation.html?foo2"; + let url3 = REQUEST_URL + "file_navigation.html?foo3"; + + let loaded = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser); + BrowserTestUtils.startLoadingURIString(gBrowser, url1); + await loaded; + + // Load another site + loaded = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser); + await SpecialPowers.spawn( + gBrowser.selectedBrowser, + [url2], + async url => (content.location.href = url) + ); + await loaded; + + // Load another site + loaded = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser); + await SpecialPowers.spawn( + gBrowser.selectedBrowser, + [url3], + async url => (content.location.href = url) + ); + await loaded; + is( + await promiseGetHistoryIndex(gBrowser.selectedBrowser), + 2, + "correct session history index after load 3" + ); + + // Go back one site by clicking the back button + info("Clicking back button"); + loaded = BrowserTestUtils.waitForLocationChange(gBrowser, url2); + let backButton = document.getElementById("back-button"); + backButton.click(); + await loaded; + is( + await promiseGetHistoryIndex(gBrowser.selectedBrowser), + 1, + "correct session history index after going back for the first time" + ); + + // Go back again + info("Clicking back button again"); + loaded = BrowserTestUtils.waitForLocationChange(gBrowser, url1); + backButton.click(); + await loaded; + is( + await promiseGetHistoryIndex(gBrowser.selectedBrowser), + 0, + "correct session history index after going back for the second time" + ); +} + +add_task(async function () { + waitForExplicitFinish(); + + await SpecialPowers.pushPrefEnv({ + set: [["dom.security.https_first", true]], + }); + + await testNavigations(); + + // If fission is enabled we also want to test the navigations with the bfcache + // in the parent. + if (SpecialPowers.getBoolPref("fission.autostart")) { + await SpecialPowers.pushPrefEnv({ + set: [["fission.bfcacheInParent", true]], + }); + + await testNavigations(); + } + + finish(); +}); diff --git a/dom/security/test/https-first/browser_schemeless.js b/dom/security/test/https-first/browser_schemeless.js new file mode 100644 index 0000000000..9687f15072 --- /dev/null +++ b/dom/security/test/https-first/browser_schemeless.js @@ -0,0 +1,191 @@ +/* Any copyright is dedicated to the Public Domain. + * https://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// We explicitly need HTTP URLs in this test +/* eslint-disable @microsoft/sdl/no-insecure-url */ + +ChromeUtils.defineLazyGetter(this, "UrlbarTestUtils", () => { + const { UrlbarTestUtils: module } = ChromeUtils.importESModule( + "resource://testing-common/UrlbarTestUtils.sys.mjs" + ); + module.init(this); + return module; +}); + +XPCOMUtils.defineLazyServiceGetter( + this, + "clipboardHelper", + "@mozilla.org/widget/clipboardhelper;1", + "nsIClipboardHelper" +); + +/** Type aInput into the address bar and press enter */ +async function runMainTest(aInput, aDesc, aExpectedScheme) { + await BrowserTestUtils.withNewTab("about:blank", async function (browser) { + const loaded = BrowserTestUtils.browserLoaded(browser, false, null, true); + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + window, + value: aInput, + }); + EventUtils.synthesizeKey("KEY_Enter"); + await loaded; + + is(browser.currentURI.scheme, aExpectedScheme, "Main test: " + aDesc); + }); +} + +/** + * Type aInput into the address bar and press ctrl+enter, + * resulting in the input being canonized first. + * This should not change schemeless HTTPS behaviour. */ +async function runCanonizedTest(aInput, aDesc, aExpectedScheme) { + await BrowserTestUtils.withNewTab("about:blank", async function (browser) { + const loaded = BrowserTestUtils.browserLoaded(browser, false, null, true); + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + window, + value: aInput, + }); + EventUtils.synthesizeKey("KEY_Enter", { ctrlKey: true }); + await loaded; + + is(browser.currentURI.scheme, aExpectedScheme, "Canonized test: " + aDesc); + }); +} + +/** + * Type aInput into the address bar and press alt+enter, + * resulting in the input being loaded in a new tab. + * This should not change schemeless HTTPS behaviour. */ +async function runNewTabTest(aInput, aDesc, aExpectedScheme) { + await BrowserTestUtils.withNewTab( + "about:about", // For alt+enter to do anything, we need to be on a page other than about:blank. + async function () { + const newTabPromise = BrowserTestUtils.waitForNewTab( + gBrowser, + null, + true + ); + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + window, + value: aInput, + }); + EventUtils.synthesizeKey("KEY_Enter", { altKey: true }); + const newTab = await newTabPromise; + + is( + newTab.linkedBrowser.currentURI.scheme, + aExpectedScheme, + "New tab test: " + aDesc + ); + + BrowserTestUtils.removeTab(newTab); + } + ); +} + +/** + * Type aInput into the address bar and press shift+enter, + * resulting in the input being loaded in a new window. + * This should not change schemeless HTTPS behaviour. */ +async function runNewWindowTest(aInput, aDesc, aExpectedScheme) { + await BrowserTestUtils.withNewTab("about:about", async function () { + const newWindowPromise = BrowserTestUtils.waitForNewWindow({ + waitForAnyURLLoaded: true, + }); + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + window, + value: aInput, + }); + EventUtils.synthesizeKey("KEY_Enter", { shiftKey: true }); + const newWindow = await newWindowPromise; + + is( + newWindow.gBrowser.selectedBrowser.currentURI.scheme, + aExpectedScheme, + "New window test: " + aDesc + ); + + await BrowserTestUtils.closeWindow(newWindow); + }); +} + +/** + * Instead of typing aInput into the address bar, copy it + * to the clipboard and use the "Paste and Go" menu entry. + * This should not change schemeless HTTPS behaviour. */ +async function runPasteAndGoTest(aInput, aDesc, aExpectedScheme) { + await BrowserTestUtils.withNewTab("about:blank", async function (browser) { + gURLBar.focus(); + await SimpleTest.promiseClipboardChange(aInput, () => { + clipboardHelper.copyString(aInput); + }); + + const loaded = BrowserTestUtils.browserLoaded(browser, false, null, true); + const textBox = gURLBar.querySelector("moz-input-box"); + const cxmenu = textBox.menupopup; + const cxmenuPromise = BrowserTestUtils.waitForEvent(cxmenu, "popupshown"); + EventUtils.synthesizeMouseAtCenter(gURLBar.inputField, { + type: "contextmenu", + button: 2, + }); + await cxmenuPromise; + const menuitem = textBox.getMenuItem("paste-and-go"); + menuitem.closest("menupopup").activateItem(menuitem); + await loaded; + + is( + browser.currentURI.scheme, + aExpectedScheme, + "Paste and go test: " + aDesc + ); + }); +} + +async function runTest(aInput, aDesc, aExpectedScheme) { + await runMainTest(aInput, aDesc, aExpectedScheme); + await runCanonizedTest(aInput, aDesc, aExpectedScheme); + await runNewTabTest(aInput, aDesc, aExpectedScheme); + await runNewWindowTest(aInput, aDesc, aExpectedScheme); + await runPasteAndGoTest(aInput, aDesc, aExpectedScheme); +} + +add_task(async function () { + requestLongerTimeout(10); + + await SpecialPowers.pushPrefEnv({ + set: [ + ["dom.security.https_first", false], + ["dom.security.https_first_schemeless", false], + ], + }); + + await runTest( + "http://example.com", + "Should not upgrade upgradeable website with explicit scheme", + "http" + ); + + await runTest( + "example.com", + "Should not upgrade upgradeable website without explicit scheme", + "http" + ); + + await SpecialPowers.pushPrefEnv({ + set: [["dom.security.https_first_schemeless", true]], + }); + + await runTest( + "http://example.com", + "Should not upgrade upgradeable website with explicit scheme", + "http" + ); + + await runTest( + "example.com", + "Should upgrade upgradeable website without explicit scheme", + "https" + ); +}); diff --git a/dom/security/test/https-first/browser_slow_download.js b/dom/security/test/https-first/browser_slow_download.js new file mode 100644 index 0000000000..1583c6d361 --- /dev/null +++ b/dom/security/test/https-first/browser_slow_download.js @@ -0,0 +1,158 @@ +"use strict"; + +ChromeUtils.defineESModuleGetters(this, { + BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.sys.mjs", +}); +// Create a uri for an https site +const testPath = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "https://example.com" +); +const TEST_URI = testPath + "file_slow_download.html"; +const EXPECTED_DOWNLOAD_URL = + "example.com/browser/dom/security/test/https-first/file_slow_download.sjs"; + +// Since the server send the complete download file after 3 seconds we need an longer timeout +requestLongerTimeout(4); + +function promisePanelOpened() { + if (DownloadsPanel.panel && DownloadsPanel.panel.state == "open") { + return Promise.resolve(); + } + return BrowserTestUtils.waitForEvent(DownloadsPanel.panel, "popupshown"); +} + +/** + * Waits for a download to finish, in case it has not finished already. + * + * @param aDownload + * The Download object to wait upon. + * + * @return {Promise} + * @resolves When the download has finished successfully. + * @rejects JavaScript exception if the download failed. + */ +function promiseDownloadStopped(aDownload) { + if (!aDownload.stopped) { + // The download is in progress, wait for the current attempt to finish and + // report any errors that may occur. + return aDownload.start(); + } + + if (aDownload.succeeded) { + return Promise.resolve(); + } + + // The download failed or was canceled. + return Promise.reject(aDownload.error || new Error("Download canceled.")); +} + +// Verifys that no background request was send +let requestCounter = 0; +function examiner() { + SpecialPowers.addObserver(this, "specialpowers-http-notify-request"); +} + +examiner.prototype = { + observe(subject, topic, data) { + if (topic !== "specialpowers-http-notify-request") { + return; + } + // On Android we have other requests appear here as well. Let's make + // sure we only evaluate requests triggered by the test. + if ( + !data.startsWith("http://example.com") && + !data.startsWith("https://example.com") + ) { + return; + } + ++requestCounter; + if (requestCounter == 1) { + is(data, TEST_URI, "Download start page is https"); + return; + } + if (requestCounter == 2) { + // The specialpowers-http-notify-request fires before the internal redirect( /upgrade) to + // https happens. + is( + data, + "http://" + EXPECTED_DOWNLOAD_URL, + "First download request is http (internal)" + ); + return; + } + if (requestCounter == 3) { + is( + data, + "https://" + EXPECTED_DOWNLOAD_URL, + "Download got upgraded to https" + ); + return; + } + ok(false, "we should never get here, but just in case"); + }, + remove() { + SpecialPowers.removeObserver(this, "specialpowers-http-notify-request"); + }, +}; + +// Test description: +// 1. Open https://example.com +// 2. Start download - location of download is http +// 3. https-first upgrades to https +// 4. Server send first part of download and after 3 seconds the rest +// 5. Complete download of text file +add_task(async function test_slow_download() { + await SpecialPowers.pushPrefEnv({ + set: [["dom.security.https_first", true]], + }); + + // remove all previous downloads + let downloadsList = await Downloads.getList(Downloads.PUBLIC); + await downloadsList.removeFinished(); + + // add observer to ensure that the background request gets canceled for the upgraded Download + this.examiner = new examiner(); + + let downloadsPanelPromise = promisePanelOpened(); + let downloadsPromise = Downloads.getList(Downloads.PUBLIC); + BrowserTestUtils.startLoadingURIString(gBrowser, TEST_URI); + // wait for downloadsPanel to open before continuing with test + await downloadsPanelPromise; + let downloadList = await downloadsPromise; + is(DownloadsPanel.isPanelShowing, true, "DownloadsPanel should be open."); + is(downloadList._downloads.length, 1, "File should be downloaded."); + let [download] = downloadList._downloads; + // wait for download to finish (with success or error) + await promiseDownloadStopped(download); + is(download.contentType, "text/plain", "File contentType should be correct."); + // ensure https-first did upgrade the scheme. + is( + download.source.url, + "https://" + EXPECTED_DOWNLOAD_URL, + "Scheme should be https." + ); + // ensure that no background request was send + is( + requestCounter, + 3, + "three requests total (download page, download http, download https/ upgraded)" + ); + // ensure that downloaded is complete + is(download.target.size, 25, "Download size is correct"); + //clean up + this.examiner.remove(); + info("cleaning up downloads"); + try { + if (Services.appinfo.OS === "WINNT") { + // We need to make the file writable to delete it on Windows. + await IOUtils.setPermissions(download.target.path, 0o600); + } + await IOUtils.remove(download.target.path); + } catch (error) { + info("The file " + download.target.path + " is not removed, " + error); + } + + await downloadList.remove(download); + await download.finalize(); +}); diff --git a/dom/security/test/https-first/browser_superfluos_auth.js b/dom/security/test/https-first/browser_superfluos_auth.js new file mode 100644 index 0000000000..961430a444 --- /dev/null +++ b/dom/security/test/https-first/browser_superfluos_auth.js @@ -0,0 +1,67 @@ +/* Any copyright is dedicated to the Public Domain. + * https://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// This test checks the superfluos auth prompt when HTTPS-First is enabled (Bug 1858565). + +const TEST_URI = "https://www.mozilla.org@example.com/"; + +const { MockRegistrar } = ChromeUtils.importESModule( + "resource://testing-common/MockRegistrar.sys.mjs" +); + +let respondMockPromptWithYes = false; + +const gMockPromptService = { + firstTimeCalled: false, + confirmExBC() { + return respondMockPromptWithYes ? 0 : 1; + }, + + QueryInterface: ChromeUtils.generateQI(["nsIPromptService"]), +}; + +var gMockPromptServiceCID = MockRegistrar.register( + "@mozilla.org/prompter;1", + gMockPromptService +); + +registerCleanupFunction(() => { + MockRegistrar.unregister(gMockPromptServiceCID); +}); + +function checkBrowserLoad(browser) { + return new Promise(resolve => { + BrowserTestUtils.browserLoaded(browser, false, null, true).then(() => { + resolve(true); + }); + BrowserTestUtils.browserStopped(browser, false, null, true).then(() => { + resolve(false); + }); + }); +} + +add_task(async function () { + await SpecialPowers.pushPrefEnv({ + set: [["dom.security.https_first", true]], + }); + + respondMockPromptWithYes = false; + let didBrowserLoadPromise = checkBrowserLoad(gBrowser.selectedBrowser); + BrowserTestUtils.startLoadingURIString(gBrowser.selectedBrowser, TEST_URI); + let didBrowserLoad = await didBrowserLoadPromise; + ok( + !didBrowserLoad, + "The browser should stop the load when the user refuses to load a page with superfluos authentication" + ); + + respondMockPromptWithYes = true; + didBrowserLoadPromise = checkBrowserLoad(gBrowser.selectedBrowser); + BrowserTestUtils.startLoadingURIString(gBrowser.selectedBrowser, TEST_URI); + didBrowserLoad = await didBrowserLoadPromise; + ok( + didBrowserLoad, + "The browser should load when the user agrees to load a page with superfluos authentication" + ); +}); diff --git a/dom/security/test/https-first/browser_upgrade_onion.js b/dom/security/test/https-first/browser_upgrade_onion.js new file mode 100644 index 0000000000..5987eda580 --- /dev/null +++ b/dom/security/test/https-first/browser_upgrade_onion.js @@ -0,0 +1,60 @@ +// This test ensures that various configurable upgrade exceptions work +"use strict"; + +async function runTest(desc, url, expectedURI) { + await BrowserTestUtils.withNewTab("about:blank", async function (browser) { + let loaded = BrowserTestUtils.browserLoaded(browser, false, null, true); + BrowserTestUtils.startLoadingURIString(browser, url); + await loaded; + + await SpecialPowers.spawn( + browser, + [desc, expectedURI], + async function (desc, expectedURI) { + // XXX ckerschb: generally we use the documentURI, but our test infra + // can not handle .onion, hence we use the URI of the failed channel + // stored on the docshell to see if the scheme was upgraded to https. + let loadedURI = content.document.documentURI; + if (loadedURI.startsWith("about:neterror")) { + loadedURI = content.docShell.failedChannel.URI.spec; + } + is(loadedURI, expectedURI, desc); + } + ); + }); +} + +// by default local addresses and .onion should *not* get upgraded +add_task(async function () { + requestLongerTimeout(2); + + await SpecialPowers.pushPrefEnv({ + set: [ + ["dom.security.https_first", true], + ["dom.security.https_only_mode", false], + ["dom.security.https_only_mode.upgrade_local", false], + ["dom.security.https_only_mode.upgrade_onion", false], + ], + }); + + await runTest( + "Hosts ending with .onion should be be exempt from HTTPS-First upgrades by default", + "http://grocery.shopping.for.one.onion/", + "http://grocery.shopping.for.one.onion/" + ); + + await SpecialPowers.pushPrefEnv({ + set: [ + ["dom.security.https_first", true], + ["dom.security.https_only_mode", false], + ["dom.security.https_only_mode.upgrade_local", false], + ["dom.security.https_only_mode.upgrade_onion", true], + ], + }); + + await runTest( + "Hosts ending with .onion should get upgraded when 'dom.security.https_only_mode.upgrade_onion' is set to true", + "http://grocery.shopping.for.one.onion/", + "https://grocery.shopping.for.one.onion/" + ); +}); diff --git a/dom/security/test/https-first/download_page.html b/dom/security/test/https-first/download_page.html new file mode 100644 index 0000000000..a828ee07db --- /dev/null +++ b/dom/security/test/https-first/download_page.html @@ -0,0 +1,22 @@ + + + + Test mixed content download by https-first + + + hi + + + + diff --git a/dom/security/test/https-first/download_server.sjs b/dom/security/test/https-first/download_server.sjs new file mode 100644 index 0000000000..7af5722e7b --- /dev/null +++ b/dom/security/test/https-first/download_server.sjs @@ -0,0 +1,16 @@ +function handleRequest(request, response) { + // Only answer to http, in case request is in https let the reply time out. + if (request.scheme === "https") { + response.processAsync(); + return; + } + + response.setHeader("Cache-Control", "no-cache", false); + // Send some file, e.g. an image + response.setHeader( + "Content-Disposition", + "attachment; filename=some-file.png" + ); + response.setHeader("Content-Type", "image/png"); + response.write("Success!"); +} diff --git a/dom/security/test/https-first/file_bad_cert.sjs b/dom/security/test/https-first/file_bad_cert.sjs new file mode 100644 index 0000000000..1a8ae08a86 --- /dev/null +++ b/dom/security/test/https-first/file_bad_cert.sjs @@ -0,0 +1,34 @@ +const RESPONSE_SUCCESS = ` + + + send message, downgraded + + + `; + +const RESPONSE_UNEXPECTED = ` + + + send message, error + + + `; + +function handleRequest(request, response) { + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + // if the received request is not http send an error + if (request.scheme === "http") { + response.write(RESPONSE_SUCCESS); + return; + } + // we should never get here; just in case, return something unexpected + response.write(RESPONSE_UNEXPECTED); +} diff --git a/dom/security/test/https-first/file_beforeunload_permit_http.html b/dom/security/test/https-first/file_beforeunload_permit_http.html new file mode 100644 index 0000000000..50459d6006 --- /dev/null +++ b/dom/security/test/https-first/file_beforeunload_permit_http.html @@ -0,0 +1,9 @@ + + + + + diff --git a/dom/security/test/https-first/file_break_endless_upgrade_downgrade_loop.sjs b/dom/security/test/https-first/file_break_endless_upgrade_downgrade_loop.sjs new file mode 100644 index 0000000000..eb64c59e97 --- /dev/null +++ b/dom/security/test/https-first/file_break_endless_upgrade_downgrade_loop.sjs @@ -0,0 +1,61 @@ +"use strict"; + +const REDIRECT_URI = + "http://example.com/tests/dom/security/test/https-first/file_break_endless_upgrade_downgrade_loop.sjs?verify"; +const DOWNGRADE_URI = + "http://example.com/tests/dom/security/test/https-first/file_downgrade_with_different_path.sjs"; +const RESPONSE_ERROR = "unexpected-query"; + +// An onload postmessage to window opener +const RESPONSE_HTTPS_SCHEME = ` + + + + + `; + +const RESPONSE_HTTP_SCHEME = ` + + + + + `; + +function handleRequest(request, response) { + response.setHeader("Cache-Control", "no-cache", false); + const query = request.queryString; + + if (query == "downgrade") { + // send same-origin downgrade from https: to http: with a different path. + // we don't consider it's an endless upgrade downgrade loop in this case. + response.setStatusLine(request.httpVersion, 302, "Found"); + response.setHeader("Location", DOWNGRADE_URI, false); + return; + } + + // handle the redirect case + if ((query >= 301 && query <= 303) || query == 307) { + // send same-origin downgrade from https: to http: again simluating + // and endless upgrade downgrade loop. + response.setStatusLine(request.httpVersion, query, "Found"); + response.setHeader("Location", REDIRECT_URI, false); + return; + } + + // Check if scheme is http:// or https:// + if (query == "verify") { + let response_content = + request.scheme === "https" ? RESPONSE_HTTPS_SCHEME : RESPONSE_HTTP_SCHEME; + response.setStatusLine(request.httpVersion, 200, "OK"); + response.write(response_content); + return; + } + + // We should never get here, but just in case ... + response.setStatusLine(request.httpVersion, 500, "OK"); + response.write("unexepcted query"); +} diff --git a/dom/security/test/https-first/file_data_uri.html b/dom/security/test/https-first/file_data_uri.html new file mode 100644 index 0000000000..69133e5079 --- /dev/null +++ b/dom/security/test/https-first/file_data_uri.html @@ -0,0 +1,16 @@ + + + + + Bug 1709069: Test that Data URI which makes a top-level request gets updated in https-first + + + + + diff --git a/dom/security/test/https-first/file_downgrade_500_responses.sjs b/dom/security/test/https-first/file_downgrade_500_responses.sjs new file mode 100644 index 0000000000..b3cfbd79dd --- /dev/null +++ b/dom/security/test/https-first/file_downgrade_500_responses.sjs @@ -0,0 +1,70 @@ +// Custom *.sjs file specifically for the needs of Bug 1709552 +"use strict"; + +const RESPONSE_SUCCESS = ` + + + send message, downgraded + + + `; + +const RESPONSE_UNEXPECTED = ` + + + send message, error + + + `; + +function handleRequest(request, response) { + // avoid confusing cache behaviour + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/html", false); + + let query = request.queryString; + // if the scheme is not https and it is the initial request + // then we rather fall through and display unexpected content + if (request.scheme === "https") { + if (query === "test1a") { + response.setStatusLine("1.1", 501, "Not Implemented"); + response.write("Not Implemented\n"); + return; + } + + if (query === "test2a") { + response.setStatusLine("1.1", 504, "Gateway Timeout"); + response.write("Gateway Timeout\n"); + return; + } + + if (query === "test3a") { + response.setStatusLine("1.1", 521, "Web Server Is Down"); + response.write("Web Server Is Down\n"); + return; + } + if (query === "test4a") { + response.setStatusLine("1.1", 530, "Railgun Error"); + response.write("Railgun Error\n"); + return; + } + if (query === "test5a") { + response.setStatusLine("1.1", 560, "Unauthorized"); + response.write("Unauthorized\n"); + return; + } + + // We should never arrive here, just in case send something unexpected + response.write(RESPONSE_UNEXPECTED); + return; + } + + // We should arrive here when the redirection was downraded successful + response.write(RESPONSE_SUCCESS); +} diff --git a/dom/security/test/https-first/file_downgrade_bad_responses.sjs b/dom/security/test/https-first/file_downgrade_bad_responses.sjs new file mode 100644 index 0000000000..1a6eea2dd1 --- /dev/null +++ b/dom/security/test/https-first/file_downgrade_bad_responses.sjs @@ -0,0 +1,73 @@ +// Custom *.sjs file specifically for the needs of Bug 1709552 +"use strict"; + +const RESPONSE_SUCCESS = ` + + + send message, downgraded + + + `; + +const RESPONSE_UNEXPECTED = ` + + + send message, error + + + `; + +function handleRequest(request, response) { + // avoid confusing cache behaviour + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/html", false); + + let query = request.queryString; + // if the scheme is not https and it is the initial request + // then we rather fall through and display unexpected content + if (request.scheme === "https") { + if (query === "test1a") { + response.setStatusLine("1.1", 400, "Bad Request"); + response.write("Bad Request\n"); + return; + } + + if (query === "test2a") { + response.setStatusLine("1.1", 403, "Forbidden"); + response.write("Forbidden\n"); + return; + } + + if (query === "test3a") { + response.setStatusLine("1.1", 404, "Not Found"); + response.write("Not Found\n"); + return; + } + if (query === "test4a") { + response.setStatusLine("1.1", 416, "Requested Range Not Satisfiable"); + response.write("Requested Range Not Satisfiable\n"); + return; + } + if (query === "test5a") { + response.setStatusLine("1.1", 418, "I'm a teapot"); + response.write("I'm a teapot\n"); + return; + } + if (query == "test6a") { + // Simulating a timeout by processing the https request + response.processAsync(); + return; + } + + // We should never arrive here, just in case send something unexpected + response.write(RESPONSE_UNEXPECTED); + return; + } + + // We should arrive here when the redirection was downraded successful + response.write(RESPONSE_SUCCESS); +} diff --git a/dom/security/test/https-first/file_downgrade_request_upgrade_request.sjs b/dom/security/test/https-first/file_downgrade_request_upgrade_request.sjs new file mode 100644 index 0000000000..6004d57eaf --- /dev/null +++ b/dom/security/test/https-first/file_downgrade_request_upgrade_request.sjs @@ -0,0 +1,52 @@ +// Custom *.sjs file specifically for the needs of Bug 1706126 +"use strict"; +// subdomain of example.com +const REDIRECT_302 = + "http://www.redirect-example.com/tests/dom/security/test/https-first/file_downgrade_request_upgrade_request.sjs"; + +const RESPONSE_SUCCESS = ` + + + send message, upgraded + + + `; + +const RESPONSE_UNEXPECTED = ` + + + send message, error + + + `; + +function handleRequest(request, response) { + // avoid confusing cache behaviour + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/html", false); + + // if the scheme is https and it is the initial request time it out + if (request.scheme === "https" && request.host === "redirect-example.com") { + // Simulating a timeout by processing the https request + response.processAsync(); + return; + } + if (request.scheme === "http" && request.host === "redirect-example.com") { + response.setStatusLine("1.1", 302, "Found"); + response.setHeader("Location", REDIRECT_302, false); + return; + } + // if the request was sent to subdomain + if (request.host.startsWith("www.")) { + response.write(RESPONSE_SUCCESS); + return; + } + // We should never arrive here, just in case send 'error' + response.write(RESPONSE_UNEXPECTED); +} diff --git a/dom/security/test/https-first/file_downgrade_view_source.sjs b/dom/security/test/https-first/file_downgrade_view_source.sjs new file mode 100644 index 0000000000..c57dd0deb8 --- /dev/null +++ b/dom/security/test/https-first/file_downgrade_view_source.sjs @@ -0,0 +1,30 @@ +"use strict"; + +function handleRequest(request, response) { + // avoid confusing cache behaviour + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/html", false); + + let query = request.queryString.split("&"); + let scheme = request.scheme; + + if (scheme === "https") { + if (query.includes("downgrade")) { + response.setStatusLine("1.1", 400, "Bad Request"); + response.write("Bad Request\n"); + return; + } + if (query.includes("upgrade")) { + response.write("view-source:https://"); + return; + } + } + + if (scheme === "http" && query.includes("downgrade")) { + response.write("view-source:http://"); + return; + } + + // We should arrive here when the redirection was downraded successful + response.write("unexpected scheme and query given"); +} diff --git a/dom/security/test/https-first/file_downgrade_with_different_path.sjs b/dom/security/test/https-first/file_downgrade_with_different_path.sjs new file mode 100644 index 0000000000..7450313d98 --- /dev/null +++ b/dom/security/test/https-first/file_downgrade_with_different_path.sjs @@ -0,0 +1,27 @@ +"use strict"; + +// An onload postmessage to window opener +const RESPONSE_HTTPS_SCHEME = ` + + + + + `; + +const RESPONSE_HTTP_SCHEME = ` + + + + + `; + +function handleRequest(request, response) { + let response_content = + request.scheme === "https" ? RESPONSE_HTTPS_SCHEME : RESPONSE_HTTP_SCHEME; + response.setStatusLine(request.httpVersion, 200, "OK"); + response.write(response_content); +} diff --git a/dom/security/test/https-first/file_download_attribute.html b/dom/security/test/https-first/file_download_attribute.html new file mode 100644 index 0000000000..453bf408b3 --- /dev/null +++ b/dom/security/test/https-first/file_download_attribute.html @@ -0,0 +1,14 @@ + + + + Test download attribute for http site + + + download by attribute + + + diff --git a/dom/security/test/https-first/file_download_attribute.sjs b/dom/security/test/https-first/file_download_attribute.sjs new file mode 100644 index 0000000000..8941da1a41 --- /dev/null +++ b/dom/security/test/https-first/file_download_attribute.sjs @@ -0,0 +1,12 @@ +function handleRequest(request, response) { + // Only answer to http, in case request is in https let the reply time out. + if (request.scheme === "https") { + response.processAsync(); + return; + } + + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Disposition", "attachment; filename=some.html"); + response.setHeader("Content-Type", "text/html"); + response.write("success!"); +} diff --git a/dom/security/test/https-first/file_form_submission.sjs b/dom/security/test/https-first/file_form_submission.sjs new file mode 100644 index 0000000000..63b248d773 --- /dev/null +++ b/dom/security/test/https-first/file_form_submission.sjs @@ -0,0 +1,84 @@ +const CC = Components.Constructor; +const BinaryInputStream = CC( + "@mozilla.org/binaryinputstream;1", + "nsIBinaryInputStream", + "setInputStream" +); + +const RESPONSE_SUCCESS = ` + + + send message, downgraded + + + `; + +const POST_FORMULAR = ` + + +
+
+ + +
+
+ + + +`; + +function handleRequest(request, response) { + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + let queryString = request.queryString; + if (request.scheme === "https" && queryString === "test=1") { + response.write(RESPONSE_SUCCESS); + return; + } + if ( + request.scheme === "https" && + (queryString === "test=2" || queryString === "test=4") + ) { + // time out request + response.processAsync(); + return; + } + if (request.scheme === "http" && queryString === "test=2") { + response.write(RESPONSE_SUCCESS); + return; + } + if (queryString === "test=3" || queryString === "test=4") { + // send post form + response.write(POST_FORMULAR); + return; + } + if (request.method == "POST") { + // extract form parameters + let body = new BinaryInputStream(request.bodyInputStream); + let avail; + let bytes = []; + while ((avail = body.available()) > 0) { + Array.prototype.push.apply(bytes, body.readByteArray(avail)); + } + let requestBodyContents = String.fromCharCode.apply(null, bytes); + + response.write(` + + + `); + + return; + } + // we should never get here; just in case, return something unexpected + response.write("do'h"); +} diff --git a/dom/security/test/https-first/file_fragment.html b/dom/security/test/https-first/file_fragment.html new file mode 100644 index 0000000000..5846d6d977 --- /dev/null +++ b/dom/security/test/https-first/file_fragment.html @@ -0,0 +1,43 @@ + + + + + Click me +
space
+ foo +
space
+ + diff --git a/dom/security/test/https-first/file_httpsfirst_speculative_connect.html b/dom/security/test/https-first/file_httpsfirst_speculative_connect.html new file mode 100644 index 0000000000..6542884191 --- /dev/null +++ b/dom/security/test/https-first/file_httpsfirst_speculative_connect.html @@ -0,0 +1 @@ +dummy file for speculative https-first upgrade test diff --git a/dom/security/test/https-first/file_httpsfirst_timeout_server.sjs b/dom/security/test/https-first/file_httpsfirst_timeout_server.sjs new file mode 100644 index 0000000000..81c4c0328b --- /dev/null +++ b/dom/security/test/https-first/file_httpsfirst_timeout_server.sjs @@ -0,0 +1,13 @@ +function handleRequest(request, response) { + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + if (request.scheme === "https") { + // Simulating a timeout by processing the https request + // async and *never* return anything! + response.processAsync(); + return; + } + // we should never get here; just in case, return something unexpected + response.write("do'h"); +} diff --git a/dom/security/test/https-first/file_mixed_content_auto_upgrade.html b/dom/security/test/https-first/file_mixed_content_auto_upgrade.html new file mode 100644 index 0000000000..7dda8909a5 --- /dev/null +++ b/dom/security/test/https-first/file_mixed_content_auto_upgrade.html @@ -0,0 +1,12 @@ + + + + Bug 1673574 - Improve Console logging for mixed content auto upgrading + + + + +