From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- dom/security/test/contentverifier/browser.ini | 19 + .../browser_verify_content_about_newtab.js | 20 + .../browser_verify_content_about_newtab2.js | 19 + .../test/contentverifier/file_about_newtab.html | 11 + .../contentverifier/file_about_newtab_bad.html | 11 + .../contentverifier/file_about_newtab_bad_csp.html | 14 + .../file_about_newtab_bad_csp_signature | 1 + .../file_about_newtab_bad_signature | 1 + .../file_about_newtab_broken_signature | 1 + .../file_about_newtab_good_signature | 1 + .../contentverifier/file_about_newtab_sri.html | 36 + .../file_about_newtab_sri_signature | 1 + .../test/contentverifier/file_contentserver.sjs | 261 ++++ dom/security/test/contentverifier/goodChain.pem | 51 + dom/security/test/contentverifier/head.js | 210 +++ dom/security/test/contentverifier/script.js | 1 + dom/security/test/contentverifier/signature.der | Bin 0 -> 103 bytes dom/security/test/contentverifier/sk.pem | 9 + dom/security/test/contentverifier/style.css | 3 + .../test/cors/file_CrossSiteXHR_cache_server.sjs | 49 + .../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 | 179 +++ dom/security/test/cors/mochitest.ini | 11 + dom/security/test/cors/test_CrossSiteXHR.html | 1461 ++++++++++++++++++++ .../test/cors/test_CrossSiteXHR_cache.html | 587 ++++++++ .../test/cors/test_CrossSiteXHR_origin.html | 174 +++ dom/security/test/csp/browser.ini | 13 + .../browser_manifest-src-override-default-src.js | 108 ++ dom/security/test/csp/browser_test_web_manifest.js | 224 +++ .../csp/browser_test_web_manifest_mixed_content.js | 53 + dom/security/test/csp/file_CSP.css | 20 + dom/security/test/csp/file_CSP.sjs | 26 + .../test/csp/file_allow_https_schemes.html | 14 + dom/security/test/csp/file_base_uri_server.sjs | 61 + dom/security/test/csp/file_blob_data_schemes.html | 49 + dom/security/test/csp/file_block_all_mcb.sjs | 76 + ..._block_all_mixed_content_frame_navigation1.html | 19 + ..._block_all_mixed_content_frame_navigation2.html | 15 + 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_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 | 43 + dom/security/test/csp/file_bug802872.sjs | 7 + .../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 | 59 + dom/security/test/csp/file_bug885433_allows.html | 38 + .../test/csp/file_bug885433_allows.html^headers^ | 1 + dom/security/test/csp/file_bug885433_blocks.html | 37 + .../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 | 28 + dom/security/test/csp/file_bug888172.sjs | 43 + 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 | 52 + 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 | 34 + .../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 | 50 + dom/security/test/csp/file_child-src_worker.html | 32 + dom/security/test/csp/file_child-src_worker.js | 4 + .../test/csp/file_child-src_worker_data.html | 33 + dom/security/test/csp/file_child_worker.js | 39 + .../test/csp/file_child_worker.js^headers^ | 1 + dom/security/test/csp/file_connect-src-fetch.html | 16 + dom/security/test/csp/file_connect-src.html | 21 + dom/security/test/csp/file_data-uri_blocked.html | 15 + .../test/csp/file_data-uri_blocked.html^headers^ | 1 + 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 | 46 + 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 | 154 +++ .../test/csp/file_evalscript_main_allowed.html | 12 + .../csp/file_evalscript_main_allowed.html^headers^ | 2 + .../test/csp/file_evalscript_main_allowed.js | 121 ++ dom/security/test/csp/file_fontloader.sjs | 58 + 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 | 33 + dom/security/test/csp/file_frameancestors.sjs | 54 + .../test/csp/file_frameancestors_main.html | 44 + dom/security/test/csp/file_frameancestors_main.js | 65 + dom/security/test/csp/file_hash_source.html | 65 + .../test/csp/file_hash_source.html^headers^ | 2 + .../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 | 79 ++ .../test/csp/file_ignore_unsafe_inline.html | 26 + ...nore_unsafe_inline_multiple_policies_server.sjs | 56 + 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_main.html | 55 + dom/security/test/csp/file_main.html^headers^ | 1 + dom/security/test/csp/file_main.js | 51 + dom/security/test/csp/file_main_worker.js | 48 + dom/security/test/csp/file_main_worker.js^headers^ | 1 + dom/security/test/csp/file_meta_element.html | 25 + dom/security/test/csp/file_meta_header_dual.sjs | 98 ++ .../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 | 50 + 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_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 | 13 + 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_redirect_content.sjs | 38 + dom/security/test/csp/file_redirect_report.sjs | 17 + 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 | 103 ++ dom/security/test/csp/file_redirects_resource.sjs | 149 ++ dom/security/test/csp/file_referrerdirective.html | 55 + dom/security/test/csp/file_report.html | 13 + dom/security/test/csp/file_report_chromescript.js | 54 + 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 | 49 + ...e_report_uri_missing_in_report_only_header.html | 0 ...uri_missing_in_report_only_header.html^headers^ | 1 + dom/security/test/csp/file_require_sri_meta.js | 1 + dom/security/test/csp/file_require_sri_meta.sjs | 54 + 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 | 4 + dom/security/test/csp/file_sandbox_pass.js | 4 + .../test/csp/file_scheme_relative_sources.js | 1 + .../test/csp/file_scheme_relative_sources.sjs | 42 + .../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 | 19 + dom/security/test/csp/file_service_worker.js | 1 + dom/security/test/csp/file_shouldprocess.html | 25 + dom/security/test/csp/file_strict_dynamic.js | 1 + .../test/csp/file_strict_dynamic_default_src.html | 14 + .../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 + .../csp/file_strict_dynamic_script_events_xbl.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 | 14 + .../test/csp/file_subframe_run_js_if_allowed.html | 13 + .../file_subframe_run_js_if_allowed.html^headers^ | 1 + dom/security/test/csp/file_testserver.sjs | 57 + dom/security/test/csp/file_upgrade_insecure.html | 78 ++ .../test/csp/file_upgrade_insecure_cors.html | 49 + .../test/csp/file_upgrade_insecure_cors_server.sjs | 62 + .../csp/file_upgrade_insecure_docwrite_iframe.sjs | 54 + .../test/csp/file_upgrade_insecure_meta.html | 79 ++ .../test/csp/file_upgrade_insecure_referrer.sjs | 55 + .../csp/file_upgrade_insecure_referrer_server.sjs | 56 + .../test/csp/file_upgrade_insecure_reporting.html | 23 + .../csp/file_upgrade_insecure_reporting_server.sjs | 80 ++ .../test/csp/file_upgrade_insecure_server.sjs | 102 ++ dom/security/test/csp/file_upgrade_insecure_wsh.py | 7 + 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 + dom/security/test/csp/mochitest.ini | 300 ++++ dom/security/test/csp/referrerdirective.sjs | 36 + 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 | 147 ++ .../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_block_all_mixed_content.html | 99 ++ ...t_block_all_mixed_content_frame_navigation.html | 46 + .../test/csp/test_blocked_uri_in_reports.html | 79 ++ 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_bug663567.html | 76 + dom/security/test/csp/test_bug802872.html | 53 + .../test/csp/test_bug836922_npolicies.html | 240 ++++ 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 | 114 ++ .../test/csp/test_child-src_worker-redirect.html | 125 ++ dom/security/test/csp/test_child-src_worker.html | 148 ++ .../test/csp/test_child-src_worker_data.html | 126 ++ dom/security/test/csp/test_connect-src.html | 129 ++ dom/security/test/csp/test_docwrite_meta.html | 86 ++ dom/security/test/csp/test_dual_header.html | 66 + dom/security/test/csp/test_evalscript.html | 59 + 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_frameancestors.html | 157 +++ dom/security/test/csp/test_hash_source.html | 135 ++ dom/security/test/csp/test_iframe_sandbox.html | 239 ++++ .../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_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_meta_element.html | 90 ++ dom/security/test/csp/test_meta_header_dual.html | 137 ++ .../test/csp/test_meta_whitespace_skipping.html | 81 ++ .../csp/test_multi_policy_injection_bypass.html | 119 ++ dom/security/test/csp/test_multipartchannel.html | 34 + dom/security/test/csp/test_nonce_source.html | 122 ++ dom/security/test/csp/test_null_baseuri.html | 67 + 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_redirects.html | 137 ++ dom/security/test/csp/test_referrerdirective.html | 145 ++ dom/security/test/csp/test_report.html | 107 ++ dom/security/test/csp/test_report_for_import.html | 112 ++ ...t_report_uri_missing_in_report_only_header.html | 47 + dom/security/test/csp/test_require_sri_meta.html | 77 ++ dom/security/test/csp/test_sandbox.html | 249 ++++ .../test/csp/test_sandbox_allow_scripts.html | 31 + .../test/csp/test_scheme_relative_sources.html | 91 ++ .../csp/test_self_none_as_hostname_confusion.html | 55 + dom/security/test/csp/test_sendbeacon.html | 34 + dom/security/test/csp/test_service_worker.html | 61 + dom/security/test/csp/test_shouldprocess.html | 98 ++ dom/security/test/csp/test_strict_dynamic.html | 134 ++ .../test/csp/test_strict_dynamic_default_src.html | 136 ++ .../csp/test_strict_dynamic_parser_inserted.html | 95 ++ .../test/csp/test_subframe_run_js_if_allowed.html | 33 + dom/security/test/csp/test_upgrade_insecure.html | 181 +++ .../test/csp/test_upgrade_insecure_cors.html | 86 ++ .../csp/test_upgrade_insecure_docwrite_iframe.html | 54 + .../test/csp/test_upgrade_insecure_referrer.html | 85 ++ .../test/csp/test_upgrade_insecure_reporting.html | 69 + dom/security/test/general/bug1277803.html | 11 + dom/security/test/general/chrome.ini | 7 + dom/security/test/general/favicon_bug1277803.ico | Bin 0 -> 1406 bytes .../file_block_script_wrong_mime_server.sjs | 34 + ...file_contentpolicytype_targeted_link_iframe.sjs | 46 + .../test/general/file_nosniff_testserver.sjs | 60 + dom/security/test/general/mochitest.ini | 9 + .../test/general/test_block_script_wrong_mime.html | 100 ++ dom/security/test/general/test_bug1277803.xul | 99 ++ ...est_contentpolicytype_targeted_link_iframe.html | 92 ++ dom/security/test/general/test_nosniff.html | 118 ++ dom/security/test/gtest/TestCSPParser.cpp | 1132 +++++++++++++++ dom/security/test/gtest/moz.build | 11 + dom/security/test/hsts/browser.ini | 19 + .../test/hsts/browser_hsts-priming_allow_active.js | 24 + .../hsts/browser_hsts-priming_allow_display.js | 24 + .../test/hsts/browser_hsts-priming_block_active.js | 24 + .../hsts/browser_hsts-priming_block_active_css.js | 24 + ...er_hsts-priming_block_active_with_redir_same.js | 24 + .../hsts/browser_hsts-priming_block_display.js | 24 + .../hsts/browser_hsts-priming_cache-timeout.js | 36 + .../hsts/browser_hsts-priming_hsts_after_mixed.js | 24 + .../hsts/browser_hsts-priming_no-duplicates.js | 30 + dom/security/test/hsts/file_1x1.png | Bin 0 -> 17811 bytes dom/security/test/hsts/file_priming-top.html | 84 ++ dom/security/test/hsts/file_priming.js | 4 + dom/security/test/hsts/file_stylesheet.css | 0 dom/security/test/hsts/file_testserver.sjs | 66 + dom/security/test/hsts/head.js | 308 +++++ .../file_bug803225_test_mailto.html | 13 + .../mixedcontentblocker/file_frameNavigation.html | 74 + .../file_frameNavigation_blankTarget.html | 32 + .../file_frameNavigation_grandchild.html | 57 + .../file_frameNavigation_innermost.html | 72 + .../file_frameNavigation_secure.html | 73 + .../file_frameNavigation_secure_grandchild.html | 58 + .../test/mixedcontentblocker/file_main.html | 261 ++++ .../mixedcontentblocker/file_main_bug803225.html | 182 +++ .../file_main_bug803225_websocket_wsh.py | 7 + .../test/mixedcontentblocker/file_server.sjs | 45 + .../test/mixedcontentblocker/mochitest.ini | 23 + .../test/mixedcontentblocker/test_bug803225.html | 152 ++ .../mixedcontentblocker/test_frameNavigation.html | 127 ++ .../test/mixedcontentblocker/test_main.html | 187 +++ dom/security/test/moz.build | 31 + dom/security/test/sri/file_bug_1271796.css | 2 + .../sri/iframe_csp_directive_style_imports.html | 6 + ...frame_csp_directive_style_imports.html^headers^ | 1 + .../test/sri/iframe_require-sri-for_main.html | 47 + .../sri/iframe_require-sri-for_main.html^headers^ | 1 + .../test/sri/iframe_require-sri-for_no_csp.html | 5 + .../test/sri/iframe_script_crossdomain.html | 135 ++ .../test/sri/iframe_script_sameorigin.html | 249 ++++ dom/security/test/sri/iframe_sri_disabled.html | 74 + .../test/sri/iframe_style_crossdomain.html | 117 ++ dom/security/test/sri/iframe_style_sameorigin.html | 164 +++ dom/security/test/sri/mochitest.ini | 57 + dom/security/test/sri/rsf_csp_worker.js | 9 + dom/security/test/sri/rsf_csp_worker.js^headers^ | 1 + dom/security/test/sri/rsf_imported.js | 1 + dom/security/test/sri/rsf_spawn_CSPd_worker.js | 3 + dom/security/test/sri/rsf_worker.js | 2 + 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/style_imported.css | 6 + dom/security/test/sri/style_importing.css | 4 + dom/security/test/sri/test_bug_1271796.html | 30 + .../test/sri/test_csp_directive_style_imports.html | 42 + .../sri/test_require-sri-for_csp_directive.html | 76 + ...est_require-sri-for_csp_directive_disabled.html | 46 + dom/security/test/sri/test_script_crossdomain.html | 18 + dom/security/test/sri/test_script_sameorigin.html | 18 + dom/security/test/sri/test_sri_disabled.html | 18 + dom/security/test/sri/test_style_crossdomain.html | 18 + dom/security/test/sri/test_style_sameorigin.html | 18 + dom/security/test/unit/test_csp_reports.js | 231 ++++ .../test_csp_upgrade_insecure_request_header.js | 107 ++ .../unit/test_isOriginPotentiallyTrustworthy.js | 47 + dom/security/test/unit/xpcshell.ini | 7 + 423 files changed, 22274 insertions(+) create mode 100644 dom/security/test/contentverifier/browser.ini create mode 100644 dom/security/test/contentverifier/browser_verify_content_about_newtab.js create mode 100644 dom/security/test/contentverifier/browser_verify_content_about_newtab2.js create mode 100644 dom/security/test/contentverifier/file_about_newtab.html create mode 100644 dom/security/test/contentverifier/file_about_newtab_bad.html create mode 100644 dom/security/test/contentverifier/file_about_newtab_bad_csp.html create mode 100644 dom/security/test/contentverifier/file_about_newtab_bad_csp_signature create mode 100644 dom/security/test/contentverifier/file_about_newtab_bad_signature create mode 100644 dom/security/test/contentverifier/file_about_newtab_broken_signature create mode 100644 dom/security/test/contentverifier/file_about_newtab_good_signature create mode 100644 dom/security/test/contentverifier/file_about_newtab_sri.html create mode 100644 dom/security/test/contentverifier/file_about_newtab_sri_signature create mode 100644 dom/security/test/contentverifier/file_contentserver.sjs create mode 100644 dom/security/test/contentverifier/goodChain.pem create mode 100644 dom/security/test/contentverifier/head.js create mode 100644 dom/security/test/contentverifier/script.js create mode 100644 dom/security/test/contentverifier/signature.der create mode 100644 dom/security/test/contentverifier/sk.pem create mode 100644 dom/security/test/contentverifier/style.css 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/mochitest.ini 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/csp/browser.ini create mode 100644 dom/security/test/csp/browser_manifest-src-override-default-src.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/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_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_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_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_child_worker.js create mode 100644 dom/security/test/csp/file_child_worker.js^headers^ 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_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_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_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_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_hash_source.html create mode 100644 dom/security/test/csp/file_hash_source.html^headers^ 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_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_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_main_worker.js create mode 100644 dom/security/test/csp/file_main_worker.js^headers^ 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_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_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_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_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_referrerdirective.html 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_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_require_sri_meta.js create mode 100644 dom/security/test/csp/file_require_sri_meta.sjs 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_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_shouldprocess.html 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_xbl.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_testserver.sjs 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_meta.html create mode 100644 dom/security/test/csp/file_upgrade_insecure_referrer.sjs create mode 100644 dom/security/test/csp/file_upgrade_insecure_referrer_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/mochitest.ini 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_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_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_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_docwrite_meta.html create mode 100644 dom/security/test/csp/test_dual_header.html create mode 100644 dom/security/test/csp/test_evalscript.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_frameancestors.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_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_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_source.html create mode 100644 dom/security/test/csp/test_null_baseuri.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_redirects.html create mode 100644 dom/security/test/csp/test_referrerdirective.html create mode 100644 dom/security/test/csp/test_report.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_require_sri_meta.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_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_shouldprocess.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_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_referrer.html create mode 100644 dom/security/test/csp/test_upgrade_insecure_reporting.html create mode 100644 dom/security/test/general/bug1277803.html create mode 100644 dom/security/test/general/chrome.ini create mode 100644 dom/security/test/general/favicon_bug1277803.ico create mode 100644 dom/security/test/general/file_block_script_wrong_mime_server.sjs create mode 100644 dom/security/test/general/file_contentpolicytype_targeted_link_iframe.sjs create mode 100644 dom/security/test/general/file_nosniff_testserver.sjs create mode 100644 dom/security/test/general/mochitest.ini create mode 100644 dom/security/test/general/test_block_script_wrong_mime.html create mode 100644 dom/security/test/general/test_bug1277803.xul create mode 100644 dom/security/test/general/test_contentpolicytype_targeted_link_iframe.html create mode 100644 dom/security/test/general/test_nosniff.html create mode 100644 dom/security/test/gtest/TestCSPParser.cpp create mode 100644 dom/security/test/gtest/moz.build create mode 100644 dom/security/test/hsts/browser.ini create mode 100644 dom/security/test/hsts/browser_hsts-priming_allow_active.js create mode 100644 dom/security/test/hsts/browser_hsts-priming_allow_display.js create mode 100644 dom/security/test/hsts/browser_hsts-priming_block_active.js create mode 100644 dom/security/test/hsts/browser_hsts-priming_block_active_css.js create mode 100644 dom/security/test/hsts/browser_hsts-priming_block_active_with_redir_same.js create mode 100644 dom/security/test/hsts/browser_hsts-priming_block_display.js create mode 100644 dom/security/test/hsts/browser_hsts-priming_cache-timeout.js create mode 100644 dom/security/test/hsts/browser_hsts-priming_hsts_after_mixed.js create mode 100644 dom/security/test/hsts/browser_hsts-priming_no-duplicates.js create mode 100644 dom/security/test/hsts/file_1x1.png create mode 100644 dom/security/test/hsts/file_priming-top.html create mode 100644 dom/security/test/hsts/file_priming.js create mode 100644 dom/security/test/hsts/file_stylesheet.css create mode 100644 dom/security/test/hsts/file_testserver.sjs create mode 100644 dom/security/test/hsts/head.js create mode 100644 dom/security/test/mixedcontentblocker/file_bug803225_test_mailto.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_server.sjs create mode 100644 dom/security/test/mixedcontentblocker/mochitest.ini 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/moz.build create mode 100644 dom/security/test/sri/file_bug_1271796.css create mode 100644 dom/security/test/sri/iframe_csp_directive_style_imports.html create mode 100644 dom/security/test/sri/iframe_csp_directive_style_imports.html^headers^ create mode 100644 dom/security/test/sri/iframe_require-sri-for_main.html create mode 100644 dom/security/test/sri/iframe_require-sri-for_main.html^headers^ create mode 100644 dom/security/test/sri/iframe_require-sri-for_no_csp.html 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_sri_disabled.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.ini create mode 100644 dom/security/test/sri/rsf_csp_worker.js create mode 100644 dom/security/test/sri/rsf_csp_worker.js^headers^ create mode 100644 dom/security/test/sri/rsf_imported.js create mode 100644 dom/security/test/sri/rsf_spawn_CSPd_worker.js create mode 100644 dom/security/test/sri/rsf_worker.js 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/style_imported.css create mode 100644 dom/security/test/sri/style_importing.css create mode 100644 dom/security/test/sri/test_bug_1271796.html create mode 100644 dom/security/test/sri/test_csp_directive_style_imports.html create mode 100644 dom/security/test/sri/test_require-sri-for_csp_directive.html create mode 100644 dom/security/test/sri/test_require-sri-for_csp_directive_disabled.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_sri_disabled.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_isOriginPotentiallyTrustworthy.js create mode 100644 dom/security/test/unit/xpcshell.ini (limited to 'dom/security/test') diff --git a/dom/security/test/contentverifier/browser.ini b/dom/security/test/contentverifier/browser.ini new file mode 100644 index 000000000..c41c2e8e8 --- /dev/null +++ b/dom/security/test/contentverifier/browser.ini @@ -0,0 +1,19 @@ +[DEFAULT] +support-files = + file_contentserver.sjs + file_about_newtab.html + file_about_newtab_bad.html + file_about_newtab_bad_csp.html + file_about_newtab_bad_csp_signature + file_about_newtab_good_signature + file_about_newtab_bad_signature + file_about_newtab_broken_signature + file_about_newtab_sri.html + file_about_newtab_sri_signature + goodChain.pem + head.js + script.js + style.css + +[browser_verify_content_about_newtab.js] +[browser_verify_content_about_newtab2.js] diff --git a/dom/security/test/contentverifier/browser_verify_content_about_newtab.js b/dom/security/test/contentverifier/browser_verify_content_about_newtab.js new file mode 100644 index 000000000..f63726ef8 --- /dev/null +++ b/dom/security/test/contentverifier/browser_verify_content_about_newtab.js @@ -0,0 +1,20 @@ + +const TESTS = [ + // { newtab (aboutURI) or regular load (url) : url, + // testStrings : expected strings in the loaded page } + { "aboutURI" : URI_GOOD, "testStrings" : [GOOD_ABOUT_STRING] }, + { "aboutURI" : URI_ERROR_HEADER, "testStrings" : [ABOUT_BLANK] }, + { "url" : URI_BAD_FILE_CACHED, "testStrings" : [BAD_ABOUT_STRING] }, + { "aboutURI" : URI_BAD_FILE_CACHED, "testStrings" : [ABOUT_BLANK] }, + { "aboutURI" : URI_GOOD, "testStrings" : [GOOD_ABOUT_STRING] }, + { "aboutURI" : URI_SRI, "testStrings" : [ + STYLESHEET_WITHOUT_SRI_BLOCKED, + STYLESHEET_WITH_SRI_LOADED, + SCRIPT_WITHOUT_SRI_BLOCKED, + SCRIPT_WITH_SRI_LOADED, + ]}, + { "aboutURI" : URI_BAD_CSP, "testStrings" : [CSP_TEST_SUCCESS_STRING] }, + { "url" : URI_CLEANUP, "testStrings" : [CLEANUP_DONE] }, +]; + +add_task(runTests); diff --git a/dom/security/test/contentverifier/browser_verify_content_about_newtab2.js b/dom/security/test/contentverifier/browser_verify_content_about_newtab2.js new file mode 100644 index 000000000..a35ff6660 --- /dev/null +++ b/dom/security/test/contentverifier/browser_verify_content_about_newtab2.js @@ -0,0 +1,19 @@ + +const TESTS = [ + // { newtab (aboutURI) or regular load (url) : url, + // testStrings : expected strings in the loaded page } + { "aboutURI" : URI_GOOD, "testStrings" : [GOOD_ABOUT_STRING] }, + { "aboutURI" : URI_ERROR_HEADER, "testStrings" : [ABOUT_BLANK] }, + { "aboutURI" : URI_KEYERROR_HEADER, "testStrings" : [ABOUT_BLANK] }, + { "aboutURI" : URI_SIGERROR_HEADER, "testStrings" : [ABOUT_BLANK] }, + { "aboutURI" : URI_NO_HEADER, "testStrings" : [ABOUT_BLANK] }, + { "aboutURI" : URI_BAD_SIG, "testStrings" : [ABOUT_BLANK] }, + { "aboutURI" : URI_BROKEN_SIG, "testStrings" : [ABOUT_BLANK] }, + { "aboutURI" : URI_BAD_X5U, "testStrings" : [ABOUT_BLANK] }, + { "aboutURI" : URI_HTTP_X5U, "testStrings" : [ABOUT_BLANK] }, + { "aboutURI" : URI_BAD_FILE, "testStrings" : [ABOUT_BLANK] }, + { "aboutURI" : URI_BAD_ALL, "testStrings" : [ABOUT_BLANK] }, + { "url" : URI_CLEANUP, "testStrings" : [CLEANUP_DONE] }, +]; + +add_task(runTests); diff --git a/dom/security/test/contentverifier/file_about_newtab.html b/dom/security/test/contentverifier/file_about_newtab.html new file mode 100644 index 000000000..f274743b9 --- /dev/null +++ b/dom/security/test/contentverifier/file_about_newtab.html @@ -0,0 +1,11 @@ + + + + + + Testpage for bug 1226928 + + + Just a fully good testpage for Bug 1226928
+ + \ No newline at end of file diff --git a/dom/security/test/contentverifier/file_about_newtab_bad.html b/dom/security/test/contentverifier/file_about_newtab_bad.html new file mode 100644 index 000000000..45899f4f4 --- /dev/null +++ b/dom/security/test/contentverifier/file_about_newtab_bad.html @@ -0,0 +1,11 @@ + + + + + + Testpage for bug 1226928 + + + Just a bad testpage for Bug 1226928
+ + \ No newline at end of file diff --git a/dom/security/test/contentverifier/file_about_newtab_bad_csp.html b/dom/security/test/contentverifier/file_about_newtab_bad_csp.html new file mode 100644 index 000000000..f8044b73f --- /dev/null +++ b/dom/security/test/contentverifier/file_about_newtab_bad_csp.html @@ -0,0 +1,14 @@ + + + + + Testpage for CSP violation (inline script) + + + CSP violation test succeeded. + + + \ No newline at end of file diff --git a/dom/security/test/contentverifier/file_about_newtab_bad_csp_signature b/dom/security/test/contentverifier/file_about_newtab_bad_csp_signature new file mode 100644 index 000000000..ded42dc9f --- /dev/null +++ b/dom/security/test/contentverifier/file_about_newtab_bad_csp_signature @@ -0,0 +1 @@ +oiypz3lb-IyJsmKNsnlp2zDrqncste8yONn9WUE6ksgJWMhSEQ9lp8vRqN0W3JPwJb6uSk16RI-tDv7uy0jxon5jL1BZpqlqIpvimg7FCQEedMKoHZwtE9an-e95sOTd \ No newline at end of file diff --git a/dom/security/test/contentverifier/file_about_newtab_bad_signature b/dom/security/test/contentverifier/file_about_newtab_bad_signature new file mode 100644 index 000000000..73a3c1e34 --- /dev/null +++ b/dom/security/test/contentverifier/file_about_newtab_bad_signature @@ -0,0 +1 @@ +KirX94omQL7lKfWGhc777t8U29enDg0O0UcJLH3PRXcvWGO8KA6mmLS3yNCFnGiTjP3vNnVtm-sUkXr4ix8WTkKABkU4fEAi77sNOkLCKw40M9sDJOesmYInS_J2AuXX \ No newline at end of file diff --git a/dom/security/test/contentverifier/file_about_newtab_broken_signature b/dom/security/test/contentverifier/file_about_newtab_broken_signature new file mode 100644 index 000000000..468a167ff --- /dev/null +++ b/dom/security/test/contentverifier/file_about_newtab_broken_signature @@ -0,0 +1 @@ +MGUCMFwSs3o95ukwBWXN1WbLgnpJ_uHWFiQROPm9zjrSqzlfiSMyLwJwIZzldWo_pBJtOwIxAJIfhXIiMVfl5NkFEJUUMxzu6FuxOJl5DCpG2wHLy9AhayLUzm4X4SpwZ6QBPapdTg \ No newline at end of file diff --git a/dom/security/test/contentverifier/file_about_newtab_good_signature b/dom/security/test/contentverifier/file_about_newtab_good_signature new file mode 100644 index 000000000..d826d49c3 --- /dev/null +++ b/dom/security/test/contentverifier/file_about_newtab_good_signature @@ -0,0 +1 @@ +HUndgHvxHNMiAe1SXoeyOOraUJCdxHqWkAYTu0Cq1KpAHcWZEVelNTvyXGbTLWj8btsmqNLAm08UlyK43q_2oO9DQfez3Fo8DhsKvm7TqgSXCkhUoxsYNanxWXhqw-Jw \ No newline at end of file diff --git a/dom/security/test/contentverifier/file_about_newtab_sri.html b/dom/security/test/contentverifier/file_about_newtab_sri.html new file mode 100644 index 000000000..4415c533a --- /dev/null +++ b/dom/security/test/contentverifier/file_about_newtab_sri.html @@ -0,0 +1,36 @@ + + + + + + Testpage for bug 1235572 + + + + Testing script loading without SRI for Bug 1235572
+
+ + + + + + + + diff --git a/dom/security/test/contentverifier/file_about_newtab_sri_signature b/dom/security/test/contentverifier/file_about_newtab_sri_signature new file mode 100644 index 000000000..b7ac17944 --- /dev/null +++ b/dom/security/test/contentverifier/file_about_newtab_sri_signature @@ -0,0 +1 @@ +yoIyAYiiEzdP1zpkRy3KaqdsjUy62Notku89cytwVwcH0x6fKsMCdM-df1wbk9N28CSTaIOW5kcSenFy5K3nU-zPIoqZDjQo6aSjF8hF6lrw1a1xbhfl9K3g4YJsuWsO \ No newline at end of file diff --git a/dom/security/test/contentverifier/file_contentserver.sjs b/dom/security/test/contentverifier/file_contentserver.sjs new file mode 100644 index 000000000..3ea49cdde --- /dev/null +++ b/dom/security/test/contentverifier/file_contentserver.sjs @@ -0,0 +1,261 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* 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/. */ +// sjs for remote about:newtab (bug 1226928) +"use strict"; + +const {classes: Cc, interfaces: Ci, utils: Cu} = Components; +Cu.import("resource://gre/modules/NetUtil.jsm"); +Cu.import("resource://gre/modules/FileUtils.jsm"); +Cu.importGlobalProperties(["URLSearchParams"]); + +const path = "browser/dom/security/test/contentverifier/"; + +const goodFileName = "file_about_newtab.html"; +const goodFileBase = path + goodFileName; +const goodFile = FileUtils.getDir("TmpD", [], true); +goodFile.append(goodFileName); +const goodSignature = path + "file_about_newtab_good_signature"; +const goodX5UString = "\"https://example.com/browser/dom/security/test/contentverifier/file_contentserver.sjs?x5u=default\""; + +const scriptFileName = "script.js"; +const cssFileName = "style.css"; +const badFile = path + "file_about_newtab_bad.html"; +const brokenSignature = path + "file_about_newtab_broken_signature"; +const badSignature = path + "file_about_newtab_bad_signature"; +const badX5UString = "\"https://example.com/browser/dom/security/test/contentverifier/file_contentserver.sjs?x5u=bad\""; +const httpX5UString = "\"http://example.com/browser/dom/security/test/contentverifier/file_contentserver.sjs?x5u=default\""; + +const sriFile = path + "file_about_newtab_sri.html"; +const sriSignature = path + "file_about_newtab_sri_signature"; + +const badCspFile = path + "file_about_newtab_bad_csp.html"; +const badCspSignature = path + "file_about_newtab_bad_csp_signature"; + +// This cert chain is copied from +// security/manager/ssl/tests/unit/test_content_signing/ +// using the certificates +// * content_signing_remote_newtab_ee.pem +// * content_signing_int.pem +// * content_signing_root.pem +const goodCertChainPath = path + "goodChain.pem"; + +const tempFileNames = [goodFileName, scriptFileName, cssFileName]; + +// we copy the file to serve as newtab to a temp directory because +// we modify it during tests. +setupTestFiles(); + +function setupTestFiles() { + for (let fileName of tempFileNames) { + let tempFile = FileUtils.getDir("TmpD", [], true); + tempFile.append(fileName); + if (!tempFile.exists()) { + let fileIn = getFileName(path + fileName, "CurWorkD"); + fileIn.copyTo(FileUtils.getDir("TmpD", [], true), ""); + } + } +} + +function getFileName(filePath, dir) { + // 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. + let testFile = + Cc["@mozilla.org/file/directory_service;1"]. + getService(Components.interfaces.nsIProperties). + get(dir, Components.interfaces.nsILocalFile); + let dirs = filePath.split("/"); + for (let i = 0; i < dirs.length; i++) { + testFile.append(dirs[i]); + } + return testFile; +} + +function loadFile(file) { + // Load a file to return it. + let testFileStream = + Cc["@mozilla.org/network/file-input-stream;1"] + .createInstance(Components.interfaces.nsIFileInputStream); + testFileStream.init(file, -1, 0, 0); + return NetUtil.readInputStreamToString(testFileStream, + testFileStream.available()); +} + +function appendToFile(aFile, content) { + try { + let file = FileUtils.openFileOutputStream(aFile, FileUtils.MODE_APPEND | + FileUtils.MODE_WRONLY); + file.write(content, content.length); + file.close(); + } catch (e) { + dump(">>> Error in appendToFile "+e); + return "Error"; + } + return "Done"; +} + +function truncateFile(aFile, length) { + let fileIn = loadFile(aFile); + fileIn = fileIn.slice(0, -length); + + try { + let file = FileUtils.openFileOutputStream(aFile, FileUtils.MODE_WRONLY | + FileUtils.MODE_TRUNCATE); + file.write(fileIn, fileIn.length); + file.close(); + } catch (e) { + dump(">>> Error in truncateFile "+e); + return "Error"; + } + return "Done"; +} + +function cleanupTestFiles() { + for (let fileName of tempFileNames) { + let tempFile = FileUtils.getDir("TmpD", [], true); + tempFile.append(fileName); + tempFile.remove(true); + } +} + +/* + * handle requests of the following form: + * sig=good&key=good&file=good&header=good&cached=no to serve pages with + * content signatures + * + * it further handles invalidateFile=yep and validateFile=yep to change the + * served file + */ +function handleRequest(request, response) { + let params = new URLSearchParams(request.queryString); + let x5uType = params.get("x5u"); + let signatureType = params.get("sig"); + let fileType = params.get("file"); + let headerType = params.get("header"); + let cached = params.get("cached"); + let invalidateFile = params.get("invalidateFile"); + let validateFile = params.get("validateFile"); + let resource = params.get("resource"); + let x5uParam = params.get("x5u"); + + if (params.get("cleanup")) { + cleanupTestFiles(); + response.setHeader("Content-Type", "text/html", false); + response.write("Done"); + return; + } + + if (resource) { + if (resource == "script") { + response.setHeader("Content-Type", "application/javascript", false); + response.write(loadFile(getFileName(scriptFileName, "TmpD"))); + } else { // resource == "css1" || resource == "css2" + response.setHeader("Content-Type", "text/css", false); + response.write(loadFile(getFileName(cssFileName, "TmpD"))); + } + return; + } + + // if invalidateFile is set, this doesn't actually return a newtab page + // but changes the served file to invalidate the signature + // NOTE: make sure to make the file valid again afterwards! + if (invalidateFile) { + let r = "Done"; + for (let fileName of tempFileNames) { + if (appendToFile(getFileName(fileName, "TmpD"), "!") != "Done") { + r = "Error"; + } + } + response.setHeader("Content-Type", "text/html", false); + response.write(r); + return; + } + + // if validateFile is set, this doesn't actually return a newtab page + // but changes the served file to make the signature valid again + if (validateFile) { + let r = "Done"; + for (let fileName of tempFileNames) { + if (truncateFile(getFileName(fileName, "TmpD"), 1) != "Done") { + r = "Error"; + } + } + response.setHeader("Content-Type", "text/html", false); + response.write(r); + return; + } + + // we have to return the certificate chain on request for the x5u parameter + if (x5uParam && x5uParam == "default") { + response.setHeader("Cache-Control", "max-age=216000", false); + response.setHeader("Content-Type", "text/plain", false); + response.write(loadFile(getFileName(goodCertChainPath, "CurWorkD"))); + return; + } + + // avoid confusing cache behaviours + if (!cached) { + response.setHeader("Cache-Control", "no-cache", false); + } else { + response.setHeader("Cache-Control", "max-age=3600", false); + } + + // send HTML to test allowed/blocked behaviours + response.setHeader("Content-Type", "text/html", false); + + // set signature header and key for Content-Signature header + /* By default a good content-signature header is returned. Any broken return + * value has to be indicated in the url. + */ + let csHeader = ""; + let x5uString = goodX5UString; + let signature = goodSignature; + let file = goodFile; + if (x5uType == "bad") { + x5uString = badX5UString; + } else if (x5uType == "http") { + x5uString = httpX5UString; + } + if (signatureType == "bad") { + signature = badSignature; + } else if (signatureType == "broken") { + signature = brokenSignature; + } else if (signatureType == "sri") { + signature = sriSignature; + } else if (signatureType == "bad-csp") { + signature = badCspSignature; + } + if (fileType == "bad") { + file = getFileName(badFile, "CurWorkD"); + } else if (fileType == "sri") { + file = getFileName(sriFile, "CurWorkD"); + } else if (fileType == "bad-csp") { + file = getFileName(badCspFile, "CurWorkD"); + } + + if (headerType == "good") { + // a valid content-signature header + csHeader = "x5u=" + x5uString + ";p384ecdsa=" + + loadFile(getFileName(signature, "CurWorkD")); + } else if (headerType == "error") { + // this content-signature header is missing ; before p384ecdsa + csHeader = "x5u=" + x5uString + "p384ecdsa=" + + loadFile(getFileName(signature, "CurWorkD")); + } else if (headerType == "errorInX5U") { + // this content-signature header is missing the keyid directive + csHeader = "x6u=" + x5uString + ";p384ecdsa=" + + loadFile(getFileName(signature, "CurWorkD")); + } else if (headerType == "errorInSignature") { + // this content-signature header is missing the p384ecdsa directive + csHeader = "x5u=" + x5uString + ";p385ecdsa=" + + loadFile(getFileName(signature, "CurWorkD")); + } + + if (csHeader) { + response.setHeader("Content-Signature", csHeader, false); + } + let result = loadFile(file); + + response.write(result); +} diff --git a/dom/security/test/contentverifier/goodChain.pem b/dom/security/test/contentverifier/goodChain.pem new file mode 100644 index 000000000..d5047cfc2 --- /dev/null +++ b/dom/security/test/contentverifier/goodChain.pem @@ -0,0 +1,51 @@ +-----BEGIN CERTIFICATE----- +MIICUzCCAT2gAwIBAgIUJ1BtYqWRwUsVaZCGPp9eTHIC04QwCwYJKoZIhvcNAQEL +MBExDzANBgNVBAMMBmludC1DQTAiGA8yMDE1MTEyODAwMDAwMFoYDzIwMTgwMjA1 +MDAwMDAwWjAUMRIwEAYDVQQDDAllZS1pbnQtQ0EwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAShaHJDNitcexiJ83kVRhWhxz+0je6GPgIpFdtgjiUt5LcTLajOmOgxU05q +nAwLCcjWOa3oMgbluoE0c6EfozDgXajJbkOD/ieHPalxA74oiM/wAvBa9xof3cyD +dKpuqc6jTjBMMBMGA1UdJQQMMAoGCCsGAQUFBwMDMDUGA1UdEQQuMCyCKnJlbW90 +ZW5ld3RhYi5jb250ZW50LXNpZ25hdHVyZS5tb3ppbGxhLm9yZzALBgkqhkiG9w0B +AQsDggEBALiLck6k50ok9ahVq45P3feY1PeUXcIYZkJd8aPDYM+0kfg5+JyJBykA +mtHWPE1QQjs7VRMfaLfu04E4UJMI2V1AON1qtgR9BQLctW85KFACg2omfiCKwJh0 +5Q8cxBFx9BpNMayqLJwHttB6oluxZFTB8CL/hfpbYpHz1bMEDCVSRP588YBrc8mV +OLqzQK+k3ewwGvfD6SvXmTny37MxqwxdTPFJNnpqzKAsQIvz8Skic9BkA1NFk0Oq +lsKKoiibbOCmwS9XY/laAkBaC3winuhciYAC0ImAopZ4PBCU0AOHGrNbhZXWYQxt +uHBj34FqvIRCqgM06JCEwN0ULgix4kI= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIC0TCCAbugAwIBAgIUPcKbBQpKwTzrrlqzM+d3z5DWiNUwCwYJKoZIhvcNAQEL +MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAw +MDBaMBExDzANBgNVBAMMBmludC1DQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72x +nAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lM +wmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF +4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20 +yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xx +j5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMlMCMwDAYDVR0TBAUwAwEB/zAT +BgNVHSUEDDAKBggrBgEFBQcDAzALBgkqhkiG9w0BAQsDggEBADDPjITgz8joxLRW +wpLxELKSgO/KQ6iAXztjMHq9ovT7Fy0fqBnQ1mMVFr+sBXLgtUCM45aip6PjhUXc +zs5Dq5STg+kz7qtmAjEQvOPcyictbgdu/K7+uMhXQhlzhOgyW88Uk5vrAezNTc/e +TvSmWp1FcgVAfaeMN/90nzD1KIHoUt7zqZIz9ub8jXPVzQNZq4vh33smZhmbdTdV +DaHUyef5cR1VTEGB+L1qzUIQqpHmD4UkMNP1nYedWfauiQhRt6Ql3rJSCRuEvsOA +iBTJlwai/EFwfyfHkOV2GNgv+A5wHHEjBtF5c4PCxQEL5Vw+mfZHLsDVqF3279ZY +lQ6jQ9g= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICzTCCAbegAwIBAgIUKRLJoCmk0A6PHrNc8CxFn//4BYcwCwYJKoZIhvcNAQEL +MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAw +MDBaMA0xCzAJBgNVBAMMAmNhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptu +Gobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO +7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgf +qDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/yt +HSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcx +uLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoyUwIzAMBgNVHRMEBTADAQH/MBMGA1Ud +JQQMMAoGCCsGAQUFBwMDMAsGCSqGSIb3DQEBCwOCAQEAABgMK6EyVIXTjD5qaxPO +DWz6yREACmAQBcowKWvfhwgi27DPSXyFGDbzTPEo+7RrIcXJkVAhLouGT51fCwTZ +zb6Sgf6ztX7VSppY9AT4utvlZKP1xQ5WhIYsMtdHCHLHIkRjeWyoBEfUx50UXNLK +Snl+A02GKYWiX+TLLg2DPN2s7v/mm8NLMQNgUlL7KakB2FHFyPa8otPpL4llg7UJ +iBTVQ0c3JoiVbwZaY1Z8QinfMXUrTK9egUC4BAcId1dE8glzA5RRlw1fTLWpGApt +hUmbDnl9N2a9NhGX323ypNzIATexafipzWe7bc4u/+bFdrUqnKUoEka73pZBdHdA +FQ== +-----END CERTIFICATE----- diff --git a/dom/security/test/contentverifier/head.js b/dom/security/test/contentverifier/head.js new file mode 100644 index 000000000..d9637d18b --- /dev/null +++ b/dom/security/test/contentverifier/head.js @@ -0,0 +1,210 @@ +/* + * Test Content-Signature for remote about:newtab + * - Bug 1226928 - allow about:newtab to load remote content + * + * This tests content-signature verification on remote about:newtab in the + * following cases (see TESTS, all failed loads display about:blank fallback): + * - good case (signature should verify and correct page is displayed) + * - reload of newtab when the siganture was invalidated after the last correct + * load + * - malformed content-signature header + * - malformed keyid directive + * - malformed p384ecdsa directive + * - wrong signature (this is not a siganture for the delivered document) + * - invalid signature (this is not even a signature) + * - loading a file that doesn't fit the key or signature + * - cache poisoning (load a malicious remote page not in newtab, subsequent + * newtab load has to load the fallback) + */ + +const ABOUT_NEWTAB_URI = "about:newtab"; + +const BASE = "https://example.com/browser/dom/security/test/contentverifier/file_contentserver.sjs?"; +const URI_GOOD = BASE + "sig=good&x5u=good&file=good&header=good"; + +const INVALIDATE_FILE = BASE + "invalidateFile=yep"; +const VALIDATE_FILE = BASE + "validateFile=yep"; + +const URI_HEADER_BASE = BASE + "sig=good&x5u=good&file=good&header="; +const URI_ERROR_HEADER = URI_HEADER_BASE + "error"; +const URI_KEYERROR_HEADER = URI_HEADER_BASE + "errorInX5U"; +const URI_SIGERROR_HEADER = URI_HEADER_BASE + "errorInSignature"; +const URI_NO_HEADER = URI_HEADER_BASE + "noHeader"; + +const URI_BAD_SIG = BASE + "sig=bad&x5u=good&file=good&header=good"; +const URI_BROKEN_SIG = BASE + "sig=broken&x5u=good&file=good&header=good"; +const URI_BAD_X5U = BASE + "sig=good&x5u=bad&file=good&header=good"; +const URI_HTTP_X5U = BASE + "sig=good&x5u=http&file=good&header=good"; +const URI_BAD_FILE = BASE + "sig=good&x5u=good&file=bad&header=good"; +const URI_BAD_ALL = BASE + "sig=bad&x5u=bad&file=bad&header=bad"; +const URI_BAD_CSP = BASE + "sig=bad-csp&x5u=good&file=bad-csp&header=good"; + +const URI_BAD_FILE_CACHED = BASE + "sig=good&x5u=good&file=bad&header=good&cached=true"; + +const GOOD_ABOUT_STRING = "Just a fully good testpage for Bug 1226928"; +const BAD_ABOUT_STRING = "Just a bad testpage for Bug 1226928"; +const ABOUT_BLANK = ""; + +const URI_CLEANUP = BASE + "cleanup=true"; +const CLEANUP_DONE = "Done"; + +const URI_SRI = BASE + "sig=sri&x5u=good&file=sri&header=good"; +const STYLESHEET_WITHOUT_SRI_BLOCKED = "Stylesheet without SRI blocked"; +const STYLESHEET_WITH_SRI_BLOCKED = "Stylesheet with SRI blocked"; +const STYLESHEET_WITH_SRI_LOADED = "Stylesheet with SRI loaded"; +const SCRIPT_WITHOUT_SRI_BLOCKED = "Script without SRI blocked"; +const SCRIPT_WITH_SRI_BLOCKED = "Script with SRI blocked"; +const SCRIPT_WITH_SRI_LOADED = "Script with SRI loaded"; + +const CSP_TEST_SUCCESS_STRING = "CSP violation test succeeded."; + +// Needs to sync with pref "security.signed_content.CSP.default". +const SIGNED_CONTENT_CSP = `{"csp-policies":[{"report-only":false,"script-src":["https://example.com","'unsafe-inline'"],"style-src":["https://example.com"]}]}`; + +var browser = null; +var aboutNewTabService = Cc["@mozilla.org/browser/aboutnewtab-service;1"] + .getService(Ci.nsIAboutNewTabService); + +function pushPrefs(...aPrefs) { + return new Promise((resolve) => { + SpecialPowers.pushPrefEnv({"set": aPrefs}, resolve); + }); +} + +/* + * run tests with input from TESTS + */ +function doTest(aExpectedStrings, reload, aUrl, aNewTabPref) { + // set about:newtab location for this test if it's a newtab test + if (aNewTabPref) { + aboutNewTabService.newTabURL = aNewTabPref; + } + + // set prefs + yield pushPrefs( + ["browser.newtabpage.remote.content-signing-test", true], + ["browser.newtabpage.remote", true], + ["security.content.signature.root_hash", + "CC:BE:04:87:74:B2:98:24:4A:C6:7A:71:BC:6F:DB:D6:C0:48:17:29:57:51:96:47:38:CC:24:C8:E4:F9:DD:CB"]); + + if (aNewTabPref === URI_BAD_CSP) { + // Use stricter CSP to test CSP violation. + yield pushPrefs(["security.signed_content.CSP.default", "script-src 'self'; style-src 'self'"]); + } else { + // Use weaker CSP to test normal content. + yield pushPrefs(["security.signed_content.CSP.default", "script-src 'self' 'unsafe-inline'; style-src 'self'"]); + } + + // start the test + yield BrowserTestUtils.withNewTab({ + gBrowser, + url: aUrl, + }, + function * (browser) { + // check if everything's set correct for testing + ok(Services.prefs.getBoolPref( + "browser.newtabpage.remote.content-signing-test"), + "sanity check: remote newtab signing test should be used"); + ok(Services.prefs.getBoolPref("browser.newtabpage.remote"), + "sanity check: remote newtab should be used"); + // we only check this if we really do a newtab test + if (aNewTabPref) { + ok(aboutNewTabService.overridden, + "sanity check: default URL for about:newtab should be overriden"); + is(aboutNewTabService.newTabURL, aNewTabPref, + "sanity check: default URL for about:newtab should return the new URL"); + } + + // Every valid remote newtab page must have built-in CSP. + let shouldHaveCSP = ((aUrl === ABOUT_NEWTAB_URI) && + (aNewTabPref === URI_GOOD || aNewTabPref === URI_SRI)); + + if (shouldHaveCSP) { + is(browser.contentDocument.nodePrincipal.cspJSON, SIGNED_CONTENT_CSP, + "Valid remote newtab page must have built-in CSP."); + } + + yield ContentTask.spawn( + browser, aExpectedStrings, function * (aExpectedStrings) { + for (let expectedString of aExpectedStrings) { + ok(content.document.documentElement.innerHTML.includes(expectedString), + "Expect the following value in the result\n" + expectedString + + "\nand got " + content.document.documentElement.innerHTML); + } + }); + + // for good test cases we check if a reload fails if the remote page + // changed from valid to invalid in the meantime + if (reload) { + yield BrowserTestUtils.withNewTab({ + gBrowser, + url: INVALIDATE_FILE, + }, + function * (browser2) { + yield ContentTask.spawn(browser2, null, function * () { + ok(content.document.documentElement.innerHTML.includes("Done"), + "Expect the following value in the result\n" + "Done" + + "\nand got " + content.document.documentElement.innerHTML); + }); + } + ); + + browser.reload(); + yield BrowserTestUtils.browserLoaded(browser); + + let expectedStrings = [ABOUT_BLANK]; + if (aNewTabPref == URI_SRI) { + expectedStrings = [ + STYLESHEET_WITHOUT_SRI_BLOCKED, + STYLESHEET_WITH_SRI_BLOCKED, + SCRIPT_WITHOUT_SRI_BLOCKED, + SCRIPT_WITH_SRI_BLOCKED + ]; + } + yield ContentTask.spawn(browser, expectedStrings, + function * (expectedStrings) { + for (let expectedString of expectedStrings) { + ok(content.document.documentElement.innerHTML.includes(expectedString), + "Expect the following value in the result\n" + expectedString + + "\nand got " + content.document.documentElement.innerHTML); + } + } + ); + + yield BrowserTestUtils.withNewTab({ + gBrowser, + url: VALIDATE_FILE, + }, + function * (browser2) { + yield ContentTask.spawn(browser2, null, function * () { + ok(content.document.documentElement.innerHTML.includes("Done"), + "Expect the following value in the result\n" + "Done" + + "\nand got " + content.document.documentElement.innerHTML); + }); + } + ); + } + } + ); +} + +function runTests() { + // run tests from TESTS + for (let i = 0; i < TESTS.length; i++) { + let testCase = TESTS[i]; + let url = "", aNewTabPref = ""; + let reload = false; + var aExpectedStrings = testCase.testStrings; + if (testCase.aboutURI) { + url = ABOUT_NEWTAB_URI; + aNewTabPref = testCase.aboutURI; + if (aNewTabPref == URI_GOOD || aNewTabPref == URI_SRI) { + reload = true; + } + } else { + url = testCase.url; + } + + yield doTest(aExpectedStrings, reload, url, aNewTabPref); + } +} diff --git a/dom/security/test/contentverifier/script.js b/dom/security/test/contentverifier/script.js new file mode 100644 index 000000000..8fd8f96b2 --- /dev/null +++ b/dom/security/test/contentverifier/script.js @@ -0,0 +1 @@ +var load=true; diff --git a/dom/security/test/contentverifier/signature.der b/dom/security/test/contentverifier/signature.der new file mode 100644 index 000000000..011b94142 Binary files /dev/null and b/dom/security/test/contentverifier/signature.der differ diff --git a/dom/security/test/contentverifier/sk.pem b/dom/security/test/contentverifier/sk.pem new file mode 100644 index 000000000..2ed514b9f --- /dev/null +++ b/dom/security/test/contentverifier/sk.pem @@ -0,0 +1,9 @@ +-----BEGIN EC PARAMETERS----- +BgUrgQQAIg== +-----END EC PARAMETERS----- +-----BEGIN EC PRIVATE KEY----- +MIGkAgEBBDAzX2TrGOr0WE92AbAl+nqnpqh25pKCLYNMTV2hJHztrkVPWOp8w0mh +scIodK8RMpagBwYFK4EEACKhZANiAATiTcWYbt0Wg63dO7OXvpptNG0ryxv+v+Js +JJ5Upr3pFus5fZyKxzP9NPzB+oFhL/xw3jMx7X5/vBGaQ2sJSiNlHVkqZgzYF6JQ +4yUyiqTY7v67CyfUPA1BJg/nxOS9m3o= +-----END EC PRIVATE KEY----- diff --git a/dom/security/test/contentverifier/style.css b/dom/security/test/contentverifier/style.css new file mode 100644 index 000000000..c7ab9ecff --- /dev/null +++ b/dom/security/test/contentverifier/style.css @@ -0,0 +1,3 @@ +#red-text { + color: red; +} 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 000000000..8ee4ddbf5 --- /dev/null +++ b/dom/security/test/cors/file_CrossSiteXHR_cache_server.sjs @@ -0,0 +1,49 @@ +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 = + eval(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 000000000..9268f0ed7 --- /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 000000000..bdb0eb440 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 000000000..2908921e2 --- /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 000000000..66d110468 --- /dev/null +++ b/dom/security/test/cors/file_CrossSiteXHR_server.sjs @@ -0,0 +1,179 @@ +const CC = Components.Constructor; +const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1", + "nsIBinaryInputStream", + "setInputStream"); + +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 = eval(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 = eval(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]); + return; + } + }); + } + + 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 = eval(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/mochitest.ini b/dom/security/test/cors/mochitest.ini new file mode 100644 index 000000000..095b0d09d --- /dev/null +++ b/dom/security/test/cors/mochitest.ini @@ -0,0 +1,11 @@ +[DEFAULT] +support-files = + file_CrossSiteXHR_cache_server.sjs + file_CrossSiteXHR_inner.html + file_CrossSiteXHR_inner.jar + file_CrossSiteXHR_inner_data.sjs + file_CrossSiteXHR_server.sjs + +[test_CrossSiteXHR.html] +[test_CrossSiteXHR_cache.html] +[test_CrossSiteXHR_origin.html] diff --git a/dom/security/test/cors/test_CrossSiteXHR.html b/dom/security/test/cors/test_CrossSiteXHR.html new file mode 100644 index 000000000..b3cda3b87 --- /dev/null +++ b/dom/security/test/cors/test_CrossSiteXHR.html @@ -0,0 +1,1461 @@ + + + + + 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 000000000..3252eff4a --- /dev/null +++ b/dom/security/test/cors/test_CrossSiteXHR_cache.html @@ -0,0 +1,587 @@ + + + + + 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 000000000..1012ae593 --- /dev/null +++ b/dom/security/test/cors/test_CrossSiteXHR_origin.html @@ -0,0 +1,174 @@ + + + + + Test for Cross Site XMLHttpRequest + + + + +

+ +

+ +
+
+
+ + diff --git a/dom/security/test/csp/browser.ini b/dom/security/test/csp/browser.ini new file mode 100644 index 000000000..0846e87fe --- /dev/null +++ b/dom/security/test/csp/browser.ini @@ -0,0 +1,13 @@ +[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 +[browser_test_web_manifest.js] +[browser_test_web_manifest_mixed_content.js] +[browser_manifest-src-override-default-src.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 000000000..0c4c7b7bc --- /dev/null +++ b/dom/security/test/csp/browser_manifest-src-override-default-src.js @@ -0,0 +1,108 @@ +/* + * Description of the tests: + * Tests check that default-src can be overridden by manifest-src. + */ +/*globals Cu, is, ok*/ +"use strict"; +const { + ManifestObtainer +} = Cu.import("resource://gre/modules/ManifestObtainer.jsm", {}); +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(`http://example.org${server}`); +const mixedURL = new URL(`http://mochi.test:8888${server}`); +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(function* () { + //jscs:enable + const testPromises = tests.map((test) => { + const tabOptions = { + gBrowser, + url: test.tabURL, + skipAnimation: true, + }; + return BrowserTestUtils.withNewTab(tabOptions, (browser) => testObtainingManifest(browser, test)); + }); + yield Promise.all(testPromises); +}); + +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 = yield 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) { + yield 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; + }); + 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", false); + return observer; +} 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 000000000..df23770ba --- /dev/null +++ b/dom/security/test/csp/browser_test_web_manifest.js @@ -0,0 +1,224 @@ +/* + * 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 +} = Cu.import("resource://gre/modules/ManifestObtainer.jsm", {}); +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}`); +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(function* () { + //jscs:enable + const testPromises = tests.map((test) => { + const tabOptions = { + gBrowser, + url: test.tabURL, + skipAnimation: true, + }; + return BrowserTestUtils.withNewTab(tabOptions, (browser) => testObtainingManifest(browser, test)); + }); + yield Promise.all(testPromises); +}); + +function* testObtainingManifest(aBrowser, aTest) { + const waitForObserver = waitForNetObserver(aTest); + // Expect an exception (from promise rejection) if there a content policy + // that is violated. + try { + const manifest = yield 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 { + yield waitForObserver; + } +} + +// Helper object used to observe policy violations when blocking is expected. +function waitForNetObserver(aTest) { + return new Promise((resolve) => { + // We don't need to wait for violation, so just resolve + if (!aTest.expected.includes("block")){ + return resolve(); + } + const observer = { + observe(subject, topic) { + SpecialPowers.removeObserver(observer, "csp-on-violate-policy"); + aTest.run(topic); + resolve(); + }, + }; + SpecialPowers.addObserver(observer, "csp-on-violate-policy", false); + }); +} 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 000000000..9238acbcd --- /dev/null +++ b/dom/security/test/csp/browser_test_web_manifest_mixed_content.js @@ -0,0 +1,53 @@ +/* + * Description of the test: + * Check that mixed content blocker works prevents fetches of + * mixed content manifests. + */ +/*globals Cu, ok*/ +"use strict"; +const { + ManifestObtainer +} = Cu.import("resource://gre/modules/ManifestObtainer.jsm", {}); +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(function* () { + //jscs:enable + const testPromises = tests.map((test) => { + const tabOptions = { + gBrowser, + url: test.tabURL, + skipAnimation: true, + }; + return BrowserTestUtils.withNewTab(tabOptions, (browser) => testObtainingManifest(browser, test)); + }); + yield Promise.all(testPromises); +}); + +function* testObtainingManifest(aBrowser, aTest) { + try { + yield ManifestObtainer.browserObtainManifest(aBrowser); + } catch (e) { + aTest.run(e); + } +} diff --git a/dom/security/test/csp/file_CSP.css b/dom/security/test/csp/file_CSP.css new file mode 100644 index 000000000..6835c4d4a --- /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 000000000..85c2df3ba --- /dev/null +++ b/dom/security/test/csp/file_CSP.sjs @@ -0,0 +1,26 @@ +// 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 000000000..787e683e8 --- /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 000000000..dfba2a061 --- /dev/null +++ b/dom/security/test/csp/file_base_uri_server.sjs @@ -0,0 +1,61 @@ +// Custom *.sjs file specifically for the needs of +// https://bugzilla.mozilla.org/show_bug.cgi?id=1263286 + +"use strict"; +Components.utils.importGlobalProperties(["URLSearchParams"]); + +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 000000000..0a4a49160 --- /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_block_all_mcb.sjs b/dom/security/test/csp/file_block_all_mcb.sjs new file mode 100644 index 000000000..731553dd7 --- /dev/null +++ b/dom/security/test/csp/file_block_all_mcb.sjs @@ -0,0 +1,76 @@ +// 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 000000000..fdc1ae87a --- /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 000000000..4c4084e9e --- /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_bug1229639.html b/dom/security/test/csp/file_bug1229639.html new file mode 100644 index 000000000..1e6152ead --- /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 000000000..0177de7a3 --- /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 000000000..18e0e5589 --- /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 000000000..25a9483ea --- /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 000000000..01c03e43f --- /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_bug663567.xsl b/dom/security/test/csp/file_bug663567.xsl new file mode 100644 index 000000000..b12b0d3b1 --- /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 000000000..93d345103 --- /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 000000000..4c6fa3c26 --- /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 000000000..93d345103 --- /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 000000000..baf7f3c6a --- /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 000000000..dc7129b0c --- /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 000000000..4c6fa3c26 --- /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 000000000..5df8086cc --- /dev/null +++ b/dom/security/test/csp/file_bug802872.js @@ -0,0 +1,43 @@ +/* + * 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 whitelisted 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 000000000..b3e3f7024 --- /dev/null +++ b/dom/security/test/csp/file_bug802872.sjs @@ -0,0 +1,7 @@ +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 000000000..6a728813a --- /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 000000000..ec6ba8c4a --- /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 000000000..3e7603421 --- /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 000000000..15e4958af --- /dev/null +++ b/dom/security/test/csp/file_bug836922_npolicies_violation.sjs @@ -0,0 +1,59 @@ +// 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 000000000..5d7aacbda --- /dev/null +++ b/dom/security/test/csp/file_bug885433_allows.html @@ -0,0 +1,38 @@ + + + + +
    +
  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 000000000..767b9ca92 --- /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 000000000..2279b33e4 --- /dev/null +++ b/dom/security/test/csp/file_bug885433_blocks.html @@ -0,0 +1,37 @@ + + + + +
    +
  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 000000000..f82598b67 --- /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 000000000..ec8c9e7e9 --- /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 000000000..4c6fa3c26 --- /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 000000000..83d36c55a --- /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 000000000..4c6fa3c26 --- /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 000000000..8b4313000 --- /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 000000000..6581fd425 --- /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 000000000..41137ea01 --- /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 000000000..6581fd425 --- /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 000000000..ae65171a5 --- /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 000000000..3abc19055 --- /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 000000000..f985ec8ce --- /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 000000000..6f9fc3f25 --- /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 000000000..27cf9b00a --- /dev/null +++ b/dom/security/test/csp/file_bug888172.html @@ -0,0 +1,28 @@ + + + +
    +
  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 000000000..03309610f --- /dev/null +++ b/dom/security/test/csp/file_bug888172.sjs @@ -0,0 +1,43 @@ +// SJS file for CSP mochitests + +Components.utils.import("resource://gre/modules/NetUtil.jsm"); + +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 = + Components.classes["@mozilla.org/file/directory_service;1"]. + getService(Components.interfaces.nsIProperties). + get("CurWorkD", Components.interfaces.nsILocalFile); + var dirs = path.split("/"); + for (var i = 0; i < dirs.length; i++) { + testHTMLFile.append(dirs[i]); + } + var testHTMLFileStream = + Components.classes["@mozilla.org/network/file-input-stream;1"]. + createInstance(Components.interfaces.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 000000000..0d4934a4a --- /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 000000000..ecb345875 --- /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 000000000..bcb907a96 --- /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 000000000..eccc1c011 --- /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 000000000..172cc09c9 --- /dev/null +++ b/dom/security/test/csp/file_bug910139.sjs @@ -0,0 +1,52 @@ +// Server side js file for bug 910139, see file test_bug910139.html for details. + +Components.utils.import("resource://gre/modules/NetUtil.jsm"); + +function loadResponseFromFile(path) { + var testHTMLFile = + Components.classes["@mozilla.org/file/directory_service;1"]. + getService(Components.interfaces.nsIProperties). + get("CurWorkD", Components.interfaces.nsILocalFile); + var dirs = path.split("/"); + for (var i = 0; i < dirs.length; i++) { + testHTMLFile.append(dirs[i]); + } + var testHTMLFileStream = + Components.classes["@mozilla.org/network/file-input-stream;1"]. + createInstance(Components.interfaces.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 000000000..29feba941 --- /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 000000000..b99abca09 --- /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 000000000..3a2e636e0 --- /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 000000000..22e176f20 --- /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 000000000..1e5f70cc3 --- /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 000000000..3534aa329 --- /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 000000000..e42102430 --- /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 000000000..b291a4a4e --- /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 000000000..53f768707 --- /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 000000000..313915302 --- /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 000000000..0e9a56a29 --- /dev/null +++ b/dom/security/test/csp/file_child-src_shared_worker.html @@ -0,0 +1,34 @@ + + + + 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 000000000..0fca1394c --- /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 000000000..a4befe4ca --- /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 000000000..188f173b8 --- /dev/null +++ b/dom/security/test/csp/file_child-src_worker-redirect.html @@ -0,0 +1,50 @@ + + + + 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 000000000..9300d3f61 --- /dev/null +++ b/dom/security/test/csp/file_child-src_worker.html @@ -0,0 +1,32 @@ + + + + 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 000000000..1d93cac6b --- /dev/null +++ b/dom/security/test/csp/file_child-src_worker.js @@ -0,0 +1,4 @@ +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 000000000..e9e22f01d --- /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_child_worker.js b/dom/security/test/csp/file_child_worker.js new file mode 100644 index 000000000..256234377 --- /dev/null +++ b/dom/security/test/csp/file_child_worker.js @@ -0,0 +1,39 @@ +function doXHR(uri) { + try { + var xhr = new XMLHttpRequest(); + xhr.open("GET", uri); + xhr.send(); + } catch(ex) {} +} + +var sameBase = "http://mochi.test:8888/tests/dom/security/test/csp/file_CSP.sjs?testid="; +var crossBase = "http://example.com/tests/dom/security/test/csp/file_CSP.sjs?testid="; + +onmessage = (e) => { + for (base of [sameBase, crossBase]) { + var prefix; + var suffix; + if (e.data.inherited == "parent") { + //Worker inherits CSP from parent worker + prefix = base + "worker_child_inherited_parent_"; + suffix = base == sameBase ? "_good" : "_bad"; + } else if (e.data.inherited == "document") { + //Worker inherits CSP from owner document -> parent worker -> subworker + prefix = base + "worker_child_inherited_document_"; + suffix = base == sameBase ? "_good" : "_bad"; + } else { + // Worker delivers CSP from HTTP header + prefix = base + "worker_child_"; + suffix = base == sameBase ? "_same_bad" : "_cross_bad"; + } + + doXHR(prefix + "xhr" + suffix); + // Fetch is likely failed in subworker + // See Bug 1273070 - Failed to fetch in subworker + // Enable fetch test after the bug is fixed + // fetch(prefix + "xhr" + suffix); + try { + importScripts(prefix + "script" + suffix); + } catch(ex) {} + } +} diff --git a/dom/security/test/csp/file_child_worker.js^headers^ b/dom/security/test/csp/file_child_worker.js^headers^ new file mode 100644 index 000000000..6581fd425 --- /dev/null +++ b/dom/security/test/csp/file_child_worker.js^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: default-src 'none' 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 000000000..ff9b2f740 --- /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 000000000..17a940a0e --- /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_data-uri_blocked.html b/dom/security/test/csp/file_data-uri_blocked.html new file mode 100644 index 000000000..293e857e3 --- /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 000000000..f593253f9 --- /dev/null +++ b/dom/security/test/csp/file_data-uri_blocked.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: default-src 'self'; img-src 'none' 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 000000000..a0f36a4bf --- /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 000000000..de725038b --- /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 000000000..292de3bec --- /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 000000000..722adc235 --- /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 000000000..d5631e783 --- /dev/null +++ b/dom/security/test/csp/file_dual_header_testserver.sjs @@ -0,0 +1,46 @@ +/* + * 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_evalscript_main.html b/dom/security/test/csp/file_evalscript_main.html new file mode 100644 index 000000000..e83c1d9ed --- /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 000000000..b91ba384d --- /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 000000000..64ab05664 --- /dev/null +++ b/dom/security/test/csp/file_evalscript_main.js @@ -0,0 +1,154 @@ +// 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); + 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); + 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."); + } + + // 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 000000000..274972d9b --- /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 000000000..0cb5288be --- /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 000000000..69e6f7a4f --- /dev/null +++ b/dom/security/test/csp/file_evalscript_main_allowed.js @@ -0,0 +1,121 @@ +// 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 { + 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."); + } + + 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 000000000..06f6e752d --- /dev/null +++ b/dom/security/test/csp/file_fontloader.sjs @@ -0,0 +1,58 @@ +// 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 000000000..fbf7390d5 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 000000000..cfff156ba --- /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 000000000..f2771d898 --- /dev/null +++ b/dom/security/test/csp/file_form_action_server.sjs @@ -0,0 +1,33 @@ +// 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_frameancestors.sjs b/dom/security/test/csp/file_frameancestors.sjs new file mode 100644 index 000000000..d0a77893f --- /dev/null +++ b/dom/security/test/csp/file_frameancestors.sjs @@ -0,0 +1,54 @@ +// 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 000000000..97f9cb9ac --- /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 000000000..caffc7257 --- /dev/null +++ b/dom/security/test/csp/file_frameancestors_main.js @@ -0,0 +1,65 @@ +// 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' + }; + + var host = { a: 'http://mochi.test:8888', b: 'http://example.com:80' }; + + 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, false); 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 000000000..47eba6cf3 --- /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 000000000..785d63391 --- /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_sandbox_document_write.html b/dom/security/test/csp/file_iframe_sandbox_document_write.html new file mode 100644 index 000000000..cdfa87c8f --- /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 000000000..bc700ed68 --- /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 000000000..cf869e07d --- /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 000000000..6de8a029e --- /dev/null +++ b/dom/security/test/csp/file_iframe_srcdoc.sjs @@ -0,0 +1,79 @@ +// Custom *.sjs file specifically for the needs of +// https://bugzilla.mozilla.org/show_bug.cgi?id=1073952 + +"use strict"; +Components.utils.importGlobalProperties(["URLSearchParams"]); + +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 000000000..b0d44b570 --- /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 000000000..0f0a8ad3e --- /dev/null +++ b/dom/security/test/csp/file_ignore_unsafe_inline_multiple_policies_server.sjs @@ -0,0 +1,56 @@ +// 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 + +Components.utils.import("resource://gre/modules/NetUtil.jsm"); + +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 = + Components.classes["@mozilla.org/file/directory_service;1"]. + getService(Components.interfaces.nsIProperties). + get("CurWorkD", Components.interfaces.nsILocalFile); + var dirs = path.split("/"); + for (var i = 0; i < dirs.length; i++) { + testHTMLFile.append(dirs[i]); + } + var testHTMLFileStream = + Components.classes["@mozilla.org/network/file-input-stream;1"]. + createInstance(Components.interfaces.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_inlinescript.html b/dom/security/test/csp/file_inlinescript.html new file mode 100644 index 000000000..55a9b9b18 --- /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 000000000..a0d296988 --- /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 000000000..7b6a25167 --- /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 000000000..9b533ef07 --- /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 000000000..621d2536b --- /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 000000000..83bb0ec0c --- /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 000000000..ea5e99344 --- /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_main.html b/dom/security/test/csp/file_main.html new file mode 100644 index 000000000..ddc838261 --- /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 000000000..3338de389 --- /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 000000000..d5afe580f --- /dev/null +++ b/dom/security/test/csp/file_main.js @@ -0,0 +1,51 @@ +function doXHR(uri, callback) { + try { + var xhr = new XMLHttpRequest(); + xhr.open("GET", uri); + xhr.responseType = "blob"; + xhr.send(); + xhr.onload = function () { + if (callback) callback(xhr.response); + } + } 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"); + +var topWorkerBlob; +var nestedWorkerBlob; + +doXHR("file_main_worker.js", function (topResponse) { + topWorkerBlob = URL.createObjectURL(topResponse); + doXHR("file_child_worker.js", function (response) { + nestedWorkerBlob = URL.createObjectURL(response); + runWorker(); + }); +}); + +function runWorker() { + // Top level worker, no subworker + // Worker does not inherit CSP from owner document + new Worker("file_main_worker.js").postMessage({inherited : "none"}); + + // Top level worker, no subworker + // Worker inherits CSP from owner document + new Worker(topWorkerBlob).postMessage({inherited : "document"}); + + // Subworker + // Worker does not inherit CSP from parent worker + new Worker("file_main_worker.js").postMessage({inherited : "none", nested : nestedWorkerBlob}); + + // Subworker + // Worker inherits CSP from parent worker + new Worker("file_main_worker.js").postMessage({inherited : "parent", nested : nestedWorkerBlob}); + + // Subworker + // Worker inherits CSP from owner document -> parent worker -> subworker + new Worker(topWorkerBlob).postMessage({inherited : "document", nested : nestedWorkerBlob}); +} diff --git a/dom/security/test/csp/file_main_worker.js b/dom/security/test/csp/file_main_worker.js new file mode 100644 index 000000000..d1314c843 --- /dev/null +++ b/dom/security/test/csp/file_main_worker.js @@ -0,0 +1,48 @@ +function doXHR(uri) { + try { + var xhr = new XMLHttpRequest(); + xhr.open("GET", uri); + xhr.send(); + } catch(ex) {} +} + +var sameBase = "http://mochi.test:8888/tests/dom/security/test/csp/file_CSP.sjs?testid="; +var crossBase = "http://example.com/tests/dom/security/test/csp/file_CSP.sjs?testid="; + +onmessage = (e) => { + // Tests of nested worker + if (e.data.nested) { + if (e.data.inherited != "none") { + // Worker inherits CSP + new Worker(e.data.nested).postMessage({inherited : e.data.inherited}); + } + else { + // Worker does not inherit CSP + new Worker("file_child_worker.js").postMessage({inherited : e.data.inherited}); + } + return; + } + + //Tests of top level worker + for (base of [sameBase, crossBase]) { + var prefix; + var suffix; + if (e.data.inherited != "none") { + // Top worker inherits CSP from owner document + prefix = base + "worker_inherited_"; + suffix = base == sameBase ? "_good" : "_bad"; + } + else { + // Top worker delivers CSP from HTTP header + prefix = base + "worker_"; + suffix = base == sameBase ? "_same_bad" : "_cross_good"; + } + + doXHR(prefix + "xhr" + suffix); + fetch(prefix + "fetch" + suffix); + try { + if (e.data.inherited == "none") suffix = base == sameBase ? "_same_good" : "_cross_bad"; + importScripts(prefix + "script" + suffix); + } catch(ex) {} + } +} diff --git a/dom/security/test/csp/file_main_worker.js^headers^ b/dom/security/test/csp/file_main_worker.js^headers^ new file mode 100644 index 000000000..3f5008ca6 --- /dev/null +++ b/dom/security/test/csp/file_main_worker.js^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: default-src 'self' blob: ; connect-src http://example.com 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 000000000..1d8ec6aa9 --- /dev/null +++ b/dom/security/test/csp/file_meta_element.html @@ -0,0 +1,25 @@ + + + + + + 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 000000000..ddc38ffe5 --- /dev/null +++ b/dom/security/test/csp/file_meta_header_dual.sjs @@ -0,0 +1,98 @@ +// 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 000000000..c0cfc8cc2 --- /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 000000000..a3cb415a9 --- /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 000000000..e1b64a922 --- /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 000000000..3fa6c7ab9 --- /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 000000000..b523073cd --- /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 000000000..d2eb58c82 --- /dev/null +++ b/dom/security/test/csp/file_multipart_testserver.sjs @@ -0,0 +1,50 @@ +// SJS file specifically for the needs of bug +// Bug 1223743 - CSP: Check baseChannel for CSP when loading multipart channel + +var CSP = "script-src 'unsafe-inline', img-src 'none'"; +var BOUNDARY = "fooboundary" + +// small red image +const IMG_BYTES = atob( + "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12" + + "P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="); + +var RESPONSE = ` + +`; + +var myTimer; + +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 == "img") { + response.setHeader("Content-Type", "image/png"); + response.write(IMG_BYTES); + return; + } + + // we should never get here - return something unexpected + response.write("d'oh"); +} 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 000000000..bf14ffe64 --- /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 000000000..865e5fe98 --- /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 000000000..f995688b1 --- /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_path_matching.html b/dom/security/test/csp/file_path_matching.html new file mode 100644 index 000000000..662fbfb8a --- /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 000000000..09286d42e --- /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 000000000..50af2b143 --- /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 000000000..a16cc90ec --- /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 000000000..49a3160f4 --- /dev/null +++ b/dom/security/test/csp/file_path_matching_redirect_server.sjs @@ -0,0 +1,13 @@ +// 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_ping.html b/dom/security/test/csp/file_ping.html new file mode 100644 index 000000000..8aaf34cc3 --- /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 000000000..2a75eef7e --- /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 000000000..c4ff8ea9f --- /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 000000000..a5c610cd7 --- /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_redirect_content.sjs b/dom/security/test/csp/file_redirect_content.sjs new file mode 100644 index 000000000..080f179cd --- /dev/null +++ b/dom/security/test/csp/file_redirect_content.sjs @@ -0,0 +1,38 @@ +// 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); + + return; +} 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 000000000..9cc7e6548 --- /dev/null +++ b/dom/security/test/csp/file_redirect_report.sjs @@ -0,0 +1,17 @@ +// 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); + return; +} 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 000000000..27df6a5fd --- /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(''); + return; +} 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 000000000..d05af88fe --- /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 000000000..ced2d0787 --- /dev/null +++ b/dom/security/test/csp/file_redirects_page.sjs @@ -0,0 +1,103 @@ +// 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: + // '); + return; + } +} 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 000000000..da138630f --- /dev/null +++ b/dom/security/test/csp/file_redirects_resource.sjs @@ -0,0 +1,149 @@ +// 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...'); + return; + } +} diff --git a/dom/security/test/csp/file_referrerdirective.html b/dom/security/test/csp/file_referrerdirective.html new file mode 100644 index 000000000..841ffe058 --- /dev/null +++ b/dom/security/test/csp/file_referrerdirective.html @@ -0,0 +1,55 @@ + + + +Subframe test for bug 965727 + + + + +Testing ... + + + + + + + diff --git a/dom/security/test/csp/file_report.html b/dom/security/test/csp/file_report.html new file mode 100644 index 000000000..fb18af805 --- /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 000000000..bf4f70edb --- /dev/null +++ b/dom/security/test/csp/file_report_chromescript.js @@ -0,0 +1,54 @@ +Components.utils.import("resource://gre/modules/Services.jsm"); + +const Ci = Components.interfaces; +const Cc = Components.classes; + +const reportURI = "http://mochi.test:8888/foo.sjs"; + +var openingObserver = { + observe: function(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); + + var segments = []; + for (var count = uploadStream.available(); count; count = uploadStream.available()) { + var data = binstream.readBytes(count); + segments.push(data); + } + + var reportText = segments.join(""); + // 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); + } + message.report = reportText; + } catch (e) { + message.error = e.toString(); + } + + sendAsyncMessage('opening-request-completed', message); + Services.obs.removeObserver(openingObserver, 'http-on-opening-request'); + } + } +}; + +Services.obs.addObserver(openingObserver, 'http-on-opening-request', false); 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 000000000..b578b77b3 --- /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 000000000..77a36faea --- /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 000000000..e69852b1b --- /dev/null +++ b/dom/security/test/csp/file_report_for_import_server.sjs @@ -0,0 +1,49 @@ +// 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 000000000..e69de29bb 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 000000000..3f2fdfe9e --- /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_require_sri_meta.js b/dom/security/test/csp/file_require_sri_meta.js new file mode 100644 index 000000000..af0113297 --- /dev/null +++ b/dom/security/test/csp/file_require_sri_meta.js @@ -0,0 +1 @@ +var foo = 24; diff --git a/dom/security/test/csp/file_require_sri_meta.sjs b/dom/security/test/csp/file_require_sri_meta.sjs new file mode 100644 index 000000000..acaf742db --- /dev/null +++ b/dom/security/test/csp/file_require_sri_meta.sjs @@ -0,0 +1,54 @@ +// custom *.sjs for Bug 1277557 +// META CSP: require-sri-for script; + +const PRE_INTEGRITY = + "" + + "" + + "Bug 1277557 - CSP require-sri-for does not block when CSP is in meta tag" + + "" + + "" + + "" + + "" + + "" + + ""; + +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 === "no-sri") { + response.write(PRE_INTEGRITY + POST_INTEGRITY); + return; + } + + if (queryString === "wrong-sri") { + response.write(PRE_INTEGRITY + WRONG_INTEGRITY + POST_INTEGRITY); + return; + } + + if (queryString === "correct-sri") { + response.write(PRE_INTEGRITY + CORRECT_INEGRITY + POST_INTEGRITY); + 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_sandbox_1.html b/dom/security/test/csp/file_sandbox_1.html new file mode 100644 index 000000000..ce1e80c86 --- /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 000000000..f934497ee --- /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 000000000..03697438a --- /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 000000000..8bed9dc59 --- /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 000000000..e4672ed05 --- /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 000000000..b37aa1bce --- /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 000000000..ba808e47d --- /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 000000000..b2d4ed094 --- /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 000000000..79894eabb --- /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 000000000..c23d87860 --- /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 000000000..3b249d410 --- /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 000000000..4f9cd8916 --- /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 000000000..29ffc191c --- /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 000000000..faab9f0fc --- /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 000000000..4705ce9de --- /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 000000000..5403ff218 --- /dev/null +++ b/dom/security/test/csp/file_sandbox_fail.js @@ -0,0 +1,4 @@ +function ok(result, desc) { + window.parent.postMessage({ok: result, desc: 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_self_none_as_hostname_confusion.html b/dom/security/test/csp/file_self_none_as_hostname_confusion.html new file mode 100644 index 000000000..16196bb19 --- /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 000000000..26af7ed9b --- /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 000000000..13202c65f --- /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 000000000..00a2b4020 --- /dev/null +++ b/dom/security/test/csp/file_service_worker.html @@ -0,0 +1,19 @@ + + + + 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 000000000..1bf583f4c --- /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_shouldprocess.html b/dom/security/test/csp/file_shouldprocess.html new file mode 100644 index 000000000..0684507e9 --- /dev/null +++ b/dom/security/test/csp/file_shouldprocess.html @@ -0,0 +1,25 @@ + + + + Helper for Test Bug 908933 + + + + + + + + + + + + + + + + + + + + + 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 000000000..09286d42e --- /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 000000000..35feacb4f --- /dev/null +++ b/dom/security/test/csp/file_strict_dynamic_default_src.html @@ -0,0 +1,14 @@ + + + + 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 000000000..09286d42e --- /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 000000000..bd53b0adb --- /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 000000000..c51fefd72 --- /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 000000000..10a0f32e4 --- /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 000000000..2a3a7d499 --- /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 000000000..9938ef2dc --- /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 000000000..088958382 --- /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_xbl.html b/dom/security/test/csp/file_strict_dynamic_script_events_xbl.html new file mode 100644 index 000000000..701ef3226 --- /dev/null +++ b/dom/security/test/csp/file_strict_dynamic_script_events_xbl.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 000000000..94b6aefb1 --- /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 000000000..d17a58f27 --- /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 000000000..f0b26da91 --- /dev/null +++ b/dom/security/test/csp/file_strict_dynamic_unsafe_eval.html @@ -0,0 +1,14 @@ + + + + Bug 1299483 - CSP: Implement 'strict-dynamic' + + +
blocked
+ + + + + \ No newline at end of file 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 000000000..3ba970ce8 --- /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 000000000..233b35931 --- /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_testserver.sjs b/dom/security/test/csp/file_testserver.sjs new file mode 100644 index 000000000..ae1826611 --- /dev/null +++ b/dom/security/test/csp/file_testserver.sjs @@ -0,0 +1,57 @@ +// SJS file for CSP mochitests +"use strict"; +Components.utils.import("resource://gre/modules/NetUtil.jsm"); +Components.utils.importGlobalProperties(["URLSearchParams"]); + +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 = + Components.classes["@mozilla.org/file/directory_service;1"]. + getService(Components.interfaces.nsIProperties). + get("CurWorkD", Components.interfaces.nsILocalFile); + + const testHTMLFileStream = + Components.classes["@mozilla.org/network/file-input-stream;1"]. + createInstance(Components.interfaces.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 + response.setHeader("Content-Type", "text/html", false); + if(query.has("file")){ + response.write(loadHTMLFromFile(query.get("file"))); + } +} 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 000000000..d104a3a24 --- /dev/null +++ b/dom/security/test/csp/file_upgrade_insecure.html @@ -0,0 +1,78 @@ + + + + + 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 000000000..e675c62e9 --- /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 000000000..33f6c3b23 --- /dev/null +++ b/dom/security/test/csp/file_upgrade_insecure_cors_server.sjs @@ -0,0 +1,62 @@ +// 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 000000000..6870a57bb --- /dev/null +++ b/dom/security/test/csp/file_upgrade_insecure_docwrite_iframe.sjs @@ -0,0 +1,54 @@ +// 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_meta.html b/dom/security/test/csp/file_upgrade_insecure_meta.html new file mode 100644 index 000000000..5f65e78ec --- /dev/null +++ b/dom/security/test/csp/file_upgrade_insecure_meta.html @@ -0,0 +1,79 @@ + + + + + + Bug 1139297 - Implement CSP upgrade-insecure-requests directive + + + + + + + + + + + + + + + + + + + + + + + + +
foo
+ + + + + + + + + + + + +
+ + +
+ + + + diff --git a/dom/security/test/csp/file_upgrade_insecure_referrer.sjs b/dom/security/test/csp/file_upgrade_insecure_referrer.sjs new file mode 100644 index 000000000..e149afa4b --- /dev/null +++ b/dom/security/test/csp/file_upgrade_insecure_referrer.sjs @@ -0,0 +1,55 @@ +// special *.sjs specifically customized for the needs of +// Bug 1139297 and Bug 663570 + +const PRE_HEAD = + "" + + "" + + ""; + + const POST_HEAD = + "" + + "Bug 1139297 - Implement CSP upgrade-insecure-requests directive" + + "" + + "" + + "" + + "" + + ""; + +const PRE_CSP = "upgrade-insecure-requests; default-src https:; "; +const CSP_REFERRER_ORIGIN = "referrer origin"; +const CSP_REFEFFER_NO_REFERRER = "referrer no-referrer"; + +function handleRequest(request, response) +{ + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + var queryString = request.queryString; + + if (queryString === "test1") { + response.setHeader("Content-Security-Policy", PRE_CSP + CSP_REFERRER_ORIGIN, false); + response.write(PRE_HEAD + POST_HEAD); + return; + } + + if (queryString === "test2") { + response.setHeader("Content-Security-Policy", PRE_CSP + CSP_REFEFFER_NO_REFERRER, false); + response.write(PRE_HEAD + POST_HEAD); + return; + } + + if (queryString === "test3") { + var metacsp = ""; + response.write(PRE_HEAD + metacsp + POST_HEAD); + return; + } + + if (queryString === "test4") { + var metacsp = ""; + response.write(PRE_HEAD + metacsp + POST_HEAD); + 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_referrer_server.sjs b/dom/security/test/csp/file_upgrade_insecure_referrer_server.sjs new file mode 100644 index 000000000..be1e6da0c --- /dev/null +++ b/dom/security/test/csp/file_upgrade_insecure_referrer_server.sjs @@ -0,0 +1,56 @@ +// Custom *.sjs file specifically for the needs of Bug: +// Bug 1139297 - Implement CSP upgrade-insecure-requests directive + +// 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); + 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 image request and return the referrer + // result back to the stored queryresult request. + if (request.queryString == "img") { + response.setHeader("Content-Type", "image/png"); + response.write(IMG_BYTES); + + let referrer = ""; + try { + referrer = request.getHeader("referer"); + } catch (e) { + referrer = ""; + } + // make sure the received image request was upgraded to https, + // otherwise we return not only the referrer but also indicate + // that the request was not upgraded to https. Note, that + // all upgrades happen in the browser before any non-secure + // request hits the wire. + referrer += (request.scheme == "https") ? + "" : " but request is not https"; + + getObjectState("queryResult", function(queryResponse) { + if (!queryResponse) { + return; + } + queryResponse.write(referrer); + 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_upgrade_insecure_reporting.html b/dom/security/test/csp/file_upgrade_insecure_reporting.html new file mode 100644 index 000000000..c78e9a784 --- /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 000000000..b9940a7fd --- /dev/null +++ b/dom/security/test/csp/file_upgrade_insecure_reporting_server.sjs @@ -0,0 +1,80 @@ +// Custom *.sjs specifically for the needs of Bug +// Bug 1139297 - Implement CSP upgrade-insecure-requests directive + +Components.utils.import("resource://gre/modules/NetUtil.jsm"); + +// 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 = + Components.classes["@mozilla.org/file/directory_service;1"]. + getService(Components.interfaces.nsIProperties). + get("CurWorkD", Components.interfaces.nsILocalFile); + var dirs = path.split("/"); + for (var i = 0; i < dirs.length; i++) { + testHTMLFile.append(dirs[i]); + } + var testHTMLFileStream = + Components.classes["@mozilla.org/network/file-input-stream;1"]. + createInstance(Components.interfaces.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 000000000..e27b97830 --- /dev/null +++ b/dom/security/test/csp/file_upgrade_insecure_server.sjs @@ -0,0 +1,102 @@ +// 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 000000000..0ae161bff --- /dev/null +++ b/dom/security/test/csp/file_upgrade_insecure_wsh.py @@ -0,0 +1,7 @@ +from mod_pywebsocket import msgutil + +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 000000000..0f6a67460 --- /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 000000000..917ab73ef --- /dev/null +++ b/dom/security/test/csp/file_web_manifest.json @@ -0,0 +1 @@ +{"name": "loaded"} \ No newline at end of file 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 000000000..e0e00c4be --- /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 000000000..b0ff9ef85 --- /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 000000000..917ab73ef --- /dev/null +++ b/dom/security/test/csp/file_web_manifest_https.json @@ -0,0 +1 @@ +{"name": "loaded"} \ No newline at end of file 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 000000000..55f17c0f9 --- /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 000000000..7ecf8eec4 --- /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/mochitest.ini b/dom/security/test/csp/mochitest.ini new file mode 100644 index 000000000..8add999c3 --- /dev/null +++ b/dom/security/test/csp/mochitest.ini @@ -0,0 +1,300 @@ +[DEFAULT] +support-files = + file_base_uri_server.sjs + file_blob_data_schemes.html + file_connect-src.html + file_connect-src-fetch.html + file_CSP.css + file_CSP.sjs + 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_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_main_worker.js + file_main_worker.js^headers^ + file_child_worker.js + file_child_worker.js^headers^ + 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_policyuri_regression_from_multipolicy.html + file_policyuri_regression_from_multipolicy.html^headers^ + file_policyuri_regression_from_multipolicy_policy + file_shouldprocess.html + file_nonce_source.html + file_nonce_source.html^headers^ + file_bug941404.html + file_bug941404_xhr.html + file_bug941404_xhr.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_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 + file_referrerdirective.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_referrer.sjs + file_upgrade_insecure_referrer_server.sjs + file_upgrade_insecure_cors.html + file_upgrade_insecure_cors_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_require_sri_meta.sjs + file_require_sri_meta.js + 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_xbl.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_iframe_srcdoc.sjs + file_iframe_sandbox_srcdoc.html + file_iframe_sandbox_srcdoc.html^headers^ + +[test_base-uri.html] +[test_blob_data_schemes.html] +[test_connect-src.html] +[test_CSP.html] +[test_allow_https_schemes.html] +[test_bug663567.html] +[test_bug802872.html] +[test_bug885433.html] +[test_bug888172.html] +[test_evalscript.html] +[test_frameancestors.html] +skip-if = toolkit == 'android' # Times out, not sure why (bug 1008445) +[test_inlinescript.html] +[test_inlinestyle.html] +[test_invalid_source_expression.html] +[test_bug836922_npolicies.html] +[test_bug886164.html] +[test_redirects.html] +[test_bug910139.html] +[test_bug909029.html] +[test_bug1229639.html] +[test_policyuri_regression_from_multipolicy.html] +[test_nonce_source.html] +[test_bug941404.html] +[test_form-action.html] +[test_hash_source.html] +[test_scheme_relative_sources.html] +[test_ignore_unsafe_inline.html] +[test_self_none_as_hostname_confusion.html] +[test_path_matching.html] +[test_path_matching_redirect.html] +[test_report_uri_missing_in_report_only_header.html] +[test_report.html] +[test_301_redirect.html] +[test_302_redirect.html] +[test_303_redirect.html] +[test_307_redirect.html] +[test_subframe_run_js_if_allowed.html] +[test_leading_wildcard.html] +[test_multi_policy_injection_bypass.html] +[test_null_baseuri.html] +[test_referrerdirective.html] +[test_dual_header.html] +[test_upgrade_insecure.html] +# no ssl support as well as websocket tests do not work (see test_websocket.html) +skip-if = toolkit == 'android' || (os != 'linux' && !debug) # Bug 1316305, Bug 1183300 +[test_upgrade_insecure_reporting.html] +skip-if = toolkit == 'android' +[test_upgrade_insecure_referrer.html] +skip-if = toolkit == 'android' +[test_upgrade_insecure_cors.html] +skip-if = toolkit == 'android' +[test_report_for_import.html] +[test_blocked_uri_in_reports.html] +[test_service_worker.html] +[test_child-src_worker.html] +[test_shouldprocess.html] +# Fennec platform does not support Java applet plugin +skip-if = toolkit == 'android' #investigate in bug 1250814 +[test_child-src_worker_data.html] +[test_child-src_worker-redirect.html] +[test_child-src_iframe.html] +[test_meta_element.html] +[test_meta_header_dual.html] +[test_docwrite_meta.html] +[test_multipartchannel.html] +[test_fontloader.html] +[test_block_all_mixed_content.html] +tags = mcb +[test_block_all_mixed_content_frame_navigation.html] +tags = mcb +[test_form_action_blocks_url.html] +[test_meta_whitespace_skipping.html] +[test_iframe_sandbox.html] +[test_iframe_sandbox_top_1.html] +[test_sandbox.html] +[test_ping.html] +[test_require_sri_meta.html] +[test_sendbeacon.html] +[test_upgrade_insecure_docwrite_iframe.html] +[test_bug1242019.html] +[test_bug1312272.html] +[test_strict_dynamic.html] +[test_strict_dynamic_parser_inserted.html] +[test_strict_dynamic_default_src.html] +[test_iframe_sandbox_srcdoc.html] +[test_iframe_srcdoc.html] +[test_sandbox_allow_scripts.html] +support-files = + file_sandbox_allow_scripts.html + file_sandbox_allow_scripts.html^headers^ diff --git a/dom/security/test/csp/referrerdirective.sjs b/dom/security/test/csp/referrerdirective.sjs new file mode 100644 index 000000000..f238ab452 --- /dev/null +++ b/dom/security/test/csp/referrerdirective.sjs @@ -0,0 +1,36 @@ +// 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 000000000..8b625a401 --- /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 000000000..616ecd9eb --- /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 000000000..9e59a18f6 --- /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 000000000..5e30b1b86 --- /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 000000000..1cde9902d --- /dev/null +++ b/dom/security/test/csp/test_CSP.html @@ -0,0 +1,147 @@ + + + + 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 000000000..713464200 --- /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 000000000..7b8dcf7e2 --- /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 000000000..37b327b10 --- /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_block_all_mixed_content.html b/dom/security/test/csp/test_block_all_mixed_content.html new file mode 100644 index 000000000..d5c4cda8b --- /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 000000000..c9d671fd7 --- /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 000000000..f68d8c03f --- /dev/null +++ b/dom/security/test/csp/test_blocked_uri_in_reports.html @@ -0,0 +1,79 @@ + + + + Bug 1069762 - Check blocked-uri in csp-reports after redirect + + + + + + + + + + diff --git a/dom/security/test/csp/test_bug1229639.html b/dom/security/test/csp/test_bug1229639.html new file mode 100644 index 000000000..cd322d36d --- /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 000000000..d57fa02bf --- /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 000000000..2cbebb844 --- /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_bug663567.html b/dom/security/test/csp/test_bug663567.html new file mode 100644 index 000000000..293aa2914 --- /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 000000000..70584c14f --- /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 000000000..8d0390eed --- /dev/null +++ b/dom/security/test/csp/test_bug836922_npolicies.html @@ -0,0 +1,240 @@ + + + + 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 000000000..22db0ed24 --- /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 000000000..74fd98458 --- /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 000000000..200e8c942 --- /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 000000000..aebfabf48 --- /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 000000000..63a7f77d1 --- /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 000000000..07f45d176 --- /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 000000000..b4ba36f89 --- /dev/null +++ b/dom/security/test/csp/test_child-src_iframe.html @@ -0,0 +1,114 @@ + + + + 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 000000000..dfb99149c --- /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 000000000..7dcbd03f6 --- /dev/null +++ b/dom/security/test/csp/test_child-src_worker.html @@ -0,0 +1,148 @@ + + + + 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 000000000..089d32dbe --- /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 000000000..5e42d9838 --- /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_docwrite_meta.html b/dom/security/test/csp/test_docwrite_meta.html new file mode 100644 index 000000000..26794199a --- /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 000000000..6d3a35fd0 --- /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_evalscript.html b/dom/security/test/csp/test_evalscript.html new file mode 100644 index 000000000..f0ec3407c --- /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_fontloader.html b/dom/security/test/csp/test_fontloader.html new file mode 100644 index 000000000..cdb177f2a --- /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 000000000..b909ca701 --- /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 000000000..ef5c8d9b4 --- /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_frameancestors.html b/dom/security/test/csp/test_frameancestors.html new file mode 100644 index 000000000..8ccbc8156 --- /dev/null +++ b/dom/security/test/csp/test_frameancestors.html @@ -0,0 +1,157 @@ + + + + Test for Content Security Policy 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 000000000..6dde11dac --- /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 000000000..f79f94135 --- /dev/null +++ b/dom/security/test/csp/test_iframe_sandbox.html @@ -0,0 +1,239 @@ + + + + + + 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 000000000..53beafcac --- /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 000000000..d9ba71824 --- /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 000000000..d9cd0606e --- /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 000000000..95b924a5e --- /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 000000000..50f9cbb8d --- /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_inlinescript.html b/dom/security/test/csp/test_inlinescript.html new file mode 100644 index 000000000..7fd5695d5 --- /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 000000000..eadcf1e38 --- /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 000000000..ad0b34999 --- /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 000000000..81c9f58ec --- /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_meta_element.html b/dom/security/test/csp/test_meta_element.html new file mode 100644 index 000000000..98c12fce8 --- /dev/null +++ b/dom/security/test/csp/test_meta_element.html @@ -0,0 +1,90 @@ + + + + + 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 000000000..4d6258d6e --- /dev/null +++ b/dom/security/test/csp/test_meta_header_dual.html @@ -0,0 +1,137 @@ + + + + + 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 000000000..67c636c3b --- /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 000000000..83a9fa265 --- /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 000000000..3dd42783b --- /dev/null +++ b/dom/security/test/csp/test_multipartchannel.html @@ -0,0 +1,34 @@ + + + + + Bug 1223743 - CSP: Check baseChannel for CSP when loading multipart channel + + + + + + + + + + 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 000000000..73a613576 --- /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 000000000..4592d582f --- /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_path_matching.html b/dom/security/test/csp/test_path_matching.html new file mode 100644 index 000000000..e02751803 --- /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 000000000..7d1044052 --- /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 000000000..a896794e1 --- /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 000000000..f69e8f558 --- /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_redirects.html b/dom/security/test/csp/test_redirects.html new file mode 100644 index 000000000..df01e3b41 --- /dev/null +++ b/dom/security/test/csp/test_redirects.html @@ -0,0 +1,137 @@ + + + + Tests for Content Security Policy during redirects + + + + +

+ + + +

+
+
+
+
+
diff --git a/dom/security/test/csp/test_referrerdirective.html b/dom/security/test/csp/test_referrerdirective.html
new file mode 100644
index 000000000..770fcc40b
--- /dev/null
+++ b/dom/security/test/csp/test_referrerdirective.html
@@ -0,0 +1,145 @@
+
+
+
+
+
+  
+  Test for Content Security Policy referrer Directive (Bug 965727)
+  
+  
+
+
+
+
+
+
+ + diff --git a/dom/security/test/csp/test_report.html b/dom/security/test/csp/test_report.html new file mode 100644 index 000000000..e8cfb8778 --- /dev/null +++ b/dom/security/test/csp/test_report.html @@ -0,0 +1,107 @@ + + + + + Test for Bug 548193 + + + + +

+ + + + + + + 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 000000000..be112d51c --- /dev/null +++ b/dom/security/test/csp/test_report_for_import.html @@ -0,0 +1,112 @@ + + + + + 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 000000000..d02911141 --- /dev/null +++ b/dom/security/test/csp/test_report_uri_missing_in_report_only_header.html @@ -0,0 +1,47 @@ + + + + + + Test for Bug 847081 + + + + +Mozilla Bug 847081 +

+ + + +
+
+
+ + diff --git a/dom/security/test/csp/test_require_sri_meta.html b/dom/security/test/csp/test_require_sri_meta.html new file mode 100644 index 000000000..a06fe122a --- /dev/null +++ b/dom/security/test/csp/test_require_sri_meta.html @@ -0,0 +1,77 @@ + + + + + Bug 1277557 - CSP require-sri-for does not block when CSP is in meta tag + + + + + + + + + + diff --git a/dom/security/test/csp/test_sandbox.html b/dom/security/test/csp/test_sandbox.html new file mode 100644 index 000000000..f0df66d6a --- /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 000000000..10acaae43 --- /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 000000000..21271cdd1 --- /dev/null +++ b/dom/security/test/csp/test_scheme_relative_sources.html @@ -0,0 +1,91 @@ + + + + Bug 921493 - CSP: test whitelisting of scheme-relative sources + + + + + + + + + + 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 000000000..e5b93c538 --- /dev/null +++ b/dom/security/test/csp/test_self_none_as_hostname_confusion.html @@ -0,0 +1,55 @@ + + + + + + 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 000000000..1b4cfbc86 --- /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 000000000..0cff84751 --- /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_shouldprocess.html b/dom/security/test/csp/test_shouldprocess.html new file mode 100644 index 000000000..5d0925167 --- /dev/null +++ b/dom/security/test/csp/test_shouldprocess.html @@ -0,0 +1,98 @@ + + + + + Test Bug 908933 + + + + + + + + + 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 000000000..00e75143f --- /dev/null +++ b/dom/security/test/csp/test_strict_dynamic.html @@ -0,0 +1,134 @@ + + + + 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 000000000..17518444e --- /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 000000000..9e588660d --- /dev/null +++ b/dom/security/test/csp/test_strict_dynamic_parser_inserted.html @@ -0,0 +1,95 @@ + + + + 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 000000000..ccc81a265 --- /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_upgrade_insecure.html b/dom/security/test/csp/test_upgrade_insecure.html new file mode 100644 index 000000000..a2b99b8db --- /dev/null +++ b/dom/security/test/csp/test_upgrade_insecure.html @@ -0,0 +1,181 @@ + + + + + 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 000000000..af296983c --- /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 000000000..822158bd7 --- /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_referrer.html b/dom/security/test/csp/test_upgrade_insecure_referrer.html new file mode 100644 index 000000000..890c57335 --- /dev/null +++ b/dom/security/test/csp/test_upgrade_insecure_referrer.html @@ -0,0 +1,85 @@ + + + + + Bug 1139297 - Implement CSP upgrade-insecure-requests directive + + + + + + + + + + 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 000000000..967654179 --- /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/general/bug1277803.html b/dom/security/test/general/bug1277803.html new file mode 100644 index 000000000..c8033551a --- /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.ini b/dom/security/test/general/chrome.ini new file mode 100644 index 000000000..94bf1ef05 --- /dev/null +++ b/dom/security/test/general/chrome.ini @@ -0,0 +1,7 @@ +[DEFAULT] +support-files = + favicon_bug1277803.ico + bug1277803.html + +[test_bug1277803.xul] +skip-if = os == 'android' diff --git a/dom/security/test/general/favicon_bug1277803.ico b/dom/security/test/general/favicon_bug1277803.ico new file mode 100644 index 000000000..d44438903 Binary files /dev/null and b/dom/security/test/general/favicon_bug1277803.ico differ 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 000000000..d6d27796c --- /dev/null +++ b/dom/security/test/general/file_block_script_wrong_mime_server.sjs @@ -0,0 +1,34 @@ +// Custom *.sjs specifically for the needs of: +// Bug 1288361 - Block scripts with wrong MIME type + +"use strict"; +Components.utils.importGlobalProperties(["URLSearchParams"]); + +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_contentpolicytype_targeted_link_iframe.sjs b/dom/security/test/general/file_contentpolicytype_targeted_link_iframe.sjs new file mode 100644 index 000000000..f0084410a --- /dev/null +++ b/dom/security/test/general/file_contentpolicytype_targeted_link_iframe.sjs @@ -0,0 +1,46 @@ +// 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_nosniff_testserver.sjs b/dom/security/test/general/file_nosniff_testserver.sjs new file mode 100644 index 000000000..0cf168a3c --- /dev/null +++ b/dom/security/test/general/file_nosniff_testserver.sjs @@ -0,0 +1,60 @@ +"use strict"; +Components.utils.importGlobalProperties(["URLSearchParams"]); + +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/mochitest.ini b/dom/security/test/general/mochitest.ini new file mode 100644 index 000000000..70c0c9fb6 --- /dev/null +++ b/dom/security/test/general/mochitest.ini @@ -0,0 +1,9 @@ +[DEFAULT] +support-files = + file_contentpolicytype_targeted_link_iframe.sjs + file_nosniff_testserver.sjs + file_block_script_wrong_mime_server.sjs + +[test_contentpolicytype_targeted_link_iframe.html] +[test_nosniff.html] +[test_block_script_wrong_mime.html] 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 000000000..f4da9c577 --- /dev/null +++ b/dom/security/test/general/test_block_script_wrong_mime.html @@ -0,0 +1,100 @@ + + + + Bug 1288361 - Block scripts with incorrect MIME type + + + + + + + + + diff --git a/dom/security/test/general/test_bug1277803.xul b/dom/security/test/general/test_bug1277803.xul new file mode 100644 index 000000000..a62285f8a --- /dev/null +++ b/dom/security/test/general/test_bug1277803.xul @@ -0,0 +1,99 @@ + + + + + + + + + + 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 000000000..7b1ab72dc --- /dev/null +++ b/dom/security/test/general/test_contentpolicytype_targeted_link_iframe.html @@ -0,0 +1,92 @@ + + + + + Bug 1255240 - Test content policy types within content policies for targeted links in iframes + + + + + + + + + + diff --git a/dom/security/test/general/test_nosniff.html b/dom/security/test/general/test_nosniff.html new file mode 100644 index 000000000..197251e68 --- /dev/null +++ b/dom/security/test/general/test_nosniff.html @@ -0,0 +1,118 @@ + + + + Bug 471020 - Add X-Content-Type-Options: nosniff support to Firefox + + + + + + + + + + + + + + + + + + + + + diff --git a/dom/security/test/gtest/TestCSPParser.cpp b/dom/security/test/gtest/TestCSPParser.cpp new file mode 100644 index 000000000..fafa7b5d9 --- /dev/null +++ b/dom/security/test/gtest/TestCSPParser.cpp @@ -0,0 +1,1132 @@ +/* -*- 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 + +#ifndef MOZILLA_INTERNAL_API +// some of the includes make use of internal string types +#define nsAString_h___ +#define nsString_h___ +#define nsStringFwd_h___ +#define nsReadableUtils_h___ +class nsACString; +class nsAString; +class nsAFlatString; +class nsAFlatCString; +class nsAdoptingString; +class nsAdoptingCString; +class nsXPIDLString; +template class nsReadingIterator; +#endif + +#include "nsIContentSecurityPolicy.h" +#include "nsNetUtil.h" +#include "nsIScriptSecurityManager.h" +#include "mozilla/dom/nsCSPContext.h" +#include "nsIPrefService.h" +#include "nsIPrefBranch.h" + +#ifndef MOZILLA_INTERNAL_API +#undef nsString_h___ +#undef nsAString_h___ +#undef nsReadableUtils_h___ +#endif + +/* + * 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 SetRequestContext + * 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; + nsCOMPtr secman = + do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, 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; + // Can't use BasePrincipal::CreateCodebasePrincipal here + // because the symbol is not visible here + rv = secman->GetCodebasePrincipal(selfURI, getter_AddRefs(selfURIPrincipal)); + NS_ENSURE_SUCCESS(rv, rv); + + // 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->SetRequestContext(nullptr, selfURIPrincipal); + 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); + bool experimentalEnabledCache = false; + bool strictDynamicEnabledCache = false; + if (prefs) + { + prefs->GetBoolPref("security.csp.experimentalEnabled", &experimentalEnabledCache); + prefs->SetBoolPref("security.csp.experimentalEnabled", true); + + prefs->GetBoolPref("security.csp.enableStrictDynamic", &strictDynamicEnabledCache); + prefs->SetBoolPref("security.csp.enableStrictDynamic", 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.experimentalEnabled", experimentalEnabledCache); + prefs->SetBoolPref("security.csp.enableStrictDynamic", strictDynamicEnabledCache); + } + + return NS_OK; +} + +// ============================= TestDirectives ======================== + +TEST(CSPParser, Directives) +{ + static const PolicyTest policies[] = + { + { "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 'sha256-siVR8vAcqP06h2ppeNwqgjr0yZ6yned4X2VF84j4GmI='", + "script-src 'sha256-siVR8vAcqP06h2ppeNwqgjr0yZ6yned4X2VF84j4GmI='" }, + { "referrer no-referrer", + "referrer no-referrer" }, + { "require-sri-for script style", + "require-sri-for script style"}, + { "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:" }, + { "default-src 'sha256-siVR8' 'strict-dynamic' 'unsafe-inline' https: ", + "default-src 'sha256-siVR8' 'unsafe-inline' https:" }, + }; + + uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest); + ASSERT_TRUE(NS_SUCCEEDED(runTestSuite(policies, policyCount, 1))); +} + +// ============================= TestKeywords ======================== + +TEST(CSPParser, Keywords) +{ + static const PolicyTest policies[] = + { + { "script-src 'self'", + "script-src http://www.selfuri.com" }, + { "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'" }, + { "img-src 'none'; script-src 'unsafe-eval' 'unsafe-inline'; default-src 'self'", + "img-src 'none'; script-src 'unsafe-eval' 'unsafe-inline'; default-src http://www.selfuri.com" }, + }; + + uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest); + ASSERT_TRUE(NS_SUCCEEDED(runTestSuite(policies, policyCount, 1))); +} + +// ============================= TestIgnoreUpperLowerCasePolicies ======================== + +TEST(CSPParser, IgnoreUpperLowerCasePolicies) +{ + static const PolicyTest policies[] = + { + { "script-src 'SELF'", + "script-src http://www.selfuri.com" }, + { "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 http://www.selfuri.com" }, + { "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='" }, + { "refERRer No-refeRRer", + "referrer no-referrer" }, + { "upgrade-INSECURE-requests", + "upgrade-insecure-requests" }, + { "sanDBox alloW-foRMs", + "sandbox allow-forms"}, + { "require-SRI-for sCript stYle", + "require-sri-for script style"}, + }; + + uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest); + ASSERT_TRUE(NS_SUCCEEDED(runTestSuite(policies, policyCount, 1))); +} + +// ============================= TestPaths ======================== + +TEST(CSPParser, Paths) +{ + static const PolicyTest policies[] = + { + { "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_" } + }; + + uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest); + ASSERT_TRUE(NS_SUCCEEDED(runTestSuite(policies, policyCount, 1))); +} + +// ============================= TestSimplePolicies ======================== + +TEST(CSPParser, SimplePolicies) +{ + static const PolicyTest policies[] = + { + { "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 http://www.selfuri.com" }, + { "style-src http://www.example.com 'self'", + "style-src http://www.example.com http://www.selfuri.com" }, + { "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 http://www.selfuri.com; 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 http://www.selfuri.com; 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 app://{app-host-is-uid}", + "default-src app://{app-host-is-uid}" }, + { " ; 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" }, + }; + + uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest); + ASSERT_TRUE(NS_SUCCEEDED(runTestSuite(policies, policyCount, 1))); +} + +// ============================= TestPoliciesWithInvalidSrc ======================== + +TEST(CSPParser, PoliciesWithInvalidSrc) +{ + static const PolicyTest policies[] = + { + { "script-src 'self'; SCRIPT-SRC http://www.example.com", + "script-src http://www.selfuri.com" }, + { "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'" }, + { "connect-src http://www.example.com/foo%zz;", + "connect-src 'none'" }, + { "script-src https://foo.com/%$", + "script-src 'none'" }, + { "require-SRI-for script elephants", + "require-sri-for script"}, + { "sandbox foo", + "sandbox"}, + }; + + // amount of tests - 1, because the latest should be ignored. + uint32_t policyCount = (sizeof(policies) / sizeof(PolicyTest)) -1; + ASSERT_TRUE(NS_SUCCEEDED(runTestSuite(policies, policyCount, 1))); +} + +// ============================= TestBadPolicies ======================== + +TEST(CSPParser, BadPolicies) +{ + static const PolicyTest policies[] = + { + { "script-sr 'self", "" }, + { "", "" }, + { "; ; ; ; ; ; ;", "" }, + { "defaut-src asdf", "" }, + { "default-src: aaa", "" }, + { "asdf http://test.com", ""}, + { "referrer", ""}, + { "referrer foo", ""}, + { "require-sri-for", ""}, + { "require-sri-for foo", ""}, + { "report-uri", ""}, + { "report-uri http://:foo", ""}, + }; + + uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest); + ASSERT_TRUE(NS_SUCCEEDED(runTestSuite(policies, policyCount, 0))); +} + +// ============================= TestGoodGeneratedPolicies ======================== + +TEST(CSPParser, GoodGeneratedPolicies) +{ + static const PolicyTest policies[] = + { + { "default-src 'self'; img-src *", + "default-src http://www.selfuri.com; 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" }, + { "default-src {app-url-is-uid}", + "default-src http://{app-url-is-uid}" }, + { "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:" }, + { "img-src {app-host-is-uid}", + "img-src http://{app-host-is-uid}" }, + { "media-src app://{app-host-is-uid}", + "media-src app://{app-host-is-uid}" }, + { "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" }, + { "object-src https://{app-host-is-uid}", + "object-src https://{app-host-is-uid}" }, + { "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 http://www.selfuri.com; script-src http://www.selfuri.com 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 http://www.selfuri.com" }, + { "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 http://www.selfuri.com" }, + { "DEFAULT-src 'self';", + "default-src http://www.selfuri.com" }, + { "default-src 'self' http://FOO.COM", + "default-src http://www.selfuri.com http://foo.com" }, + { "default-src 'self' HTTP://foo.com", + "default-src http://www.selfuri.com http://foo.com" }, + { "default-src 'NONE'", + "default-src 'none'" }, + { "script-src policy-uri ", + "script-src http://policy-uri" }, + { "img-src 'self'; ", + "img-src http://www.selfuri.com" }, + { "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 http://www.selfuri.com" }, + { "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" }, + { "default-src 'none'; frame-ancestors 'self'", + "default-src 'none'; frame-ancestors http://www.selfuri.com" }, + { "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 http://www.selfuri.com; frame-ancestors http://www.selfuri.com" }, + { "frame-ancestors http://bar.com/foo.png", + "frame-ancestors http://bar.com/foo.png" }, + }; + + uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest); + ASSERT_TRUE(NS_SUCCEEDED(runTestSuite(policies, policyCount, 1))); +} + +// ============================= TestBadGeneratedPolicies ======================== + +TEST(CSPParser, BadGeneratedPolicies) +{ + static const PolicyTest policies[] = + { + { "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", ""}, + }; + + uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest); + ASSERT_TRUE(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[] = + { + { "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////////////" }, + }; + + uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest); + ASSERT_TRUE(NS_SUCCEEDED(runTestSuite(policies, policyCount, 1))); +} + +// ============ TestBadGeneratedPoliciesForPathHandling ============ + +TEST(CSPParser, BadGeneratedPoliciesForPathHandling) +{ + static const PolicyTest policies[] = + { + { "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'" }, + }; + + uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest); + ASSERT_TRUE(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/moz.build b/dom/security/test/gtest/moz.build new file mode 100644 index 000000000..e927e7bfa --- /dev/null +++ b/dom/security/test/gtest/moz.build @@ -0,0 +1,11 @@ +# -*- 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', +] + +FINAL_LIBRARY = 'xul-gtest' diff --git a/dom/security/test/hsts/browser.ini b/dom/security/test/hsts/browser.ini new file mode 100644 index 000000000..ae75031df --- /dev/null +++ b/dom/security/test/hsts/browser.ini @@ -0,0 +1,19 @@ +[DEFAULT] +skip-if = debug # bug 1311599, bug 1311239, etc +support-files = + head.js + file_priming-top.html + file_testserver.sjs + file_1x1.png + file_priming.js + file_stylesheet.css + +[browser_hsts-priming_allow_active.js] +[browser_hsts-priming_block_active.js] +[browser_hsts-priming_hsts_after_mixed.js] +[browser_hsts-priming_allow_display.js] +[browser_hsts-priming_block_display.js] +[browser_hsts-priming_block_active_css.js] +[browser_hsts-priming_block_active_with_redir_same.js] +[browser_hsts-priming_no-duplicates.js] +[browser_hsts-priming_cache-timeout.js] diff --git a/dom/security/test/hsts/browser_hsts-priming_allow_active.js b/dom/security/test/hsts/browser_hsts-priming_allow_active.js new file mode 100644 index 000000000..a932b31b3 --- /dev/null +++ b/dom/security/test/hsts/browser_hsts-priming_allow_active.js @@ -0,0 +1,24 @@ +/* + * Description of the test: + * Check that HSTS priming occurs correctly with mixed content when active + * content is allowed. + */ +'use strict'; + +//jscs:disable +add_task(function*() { + //jscs:enable + Services.obs.addObserver(Observer, "console-api-log-event", false); + Services.obs.addObserver(Observer, "http-on-examine-response", false); + registerCleanupFunction(do_cleanup); + + let which = "allow_active"; + + SetupPrefTestEnvironment(which); + + for (let server of Object.keys(test_servers)) { + yield execute_test(server, test_settings[which].mimetype); + } + + SpecialPowers.popPrefEnv(); +}); diff --git a/dom/security/test/hsts/browser_hsts-priming_allow_display.js b/dom/security/test/hsts/browser_hsts-priming_allow_display.js new file mode 100644 index 000000000..06546ca65 --- /dev/null +++ b/dom/security/test/hsts/browser_hsts-priming_allow_display.js @@ -0,0 +1,24 @@ +/* + * Description of the test: + * Check that HSTS priming occurs correctly with mixed content when display + * content is allowed. + */ +'use strict'; + +//jscs:disable +add_task(function*() { + //jscs:enable + Services.obs.addObserver(Observer, "console-api-log-event", false); + Services.obs.addObserver(Observer, "http-on-examine-response", false); + registerCleanupFunction(do_cleanup); + + let which = "allow_display"; + + SetupPrefTestEnvironment(which); + + for (let server of Object.keys(test_servers)) { + yield execute_test(server, test_settings[which].mimetype); + } + + SpecialPowers.popPrefEnv(); +}); diff --git a/dom/security/test/hsts/browser_hsts-priming_block_active.js b/dom/security/test/hsts/browser_hsts-priming_block_active.js new file mode 100644 index 000000000..a5478b185 --- /dev/null +++ b/dom/security/test/hsts/browser_hsts-priming_block_active.js @@ -0,0 +1,24 @@ +/* + * Description of the test: + * Check that HSTS priming occurs correctly with mixed content when active + * content is blocked. + */ +'use strict'; + +//jscs:disable +add_task(function*() { + //jscs:enable + Services.obs.addObserver(Observer, "console-api-log-event", false); + Services.obs.addObserver(Observer, "http-on-examine-response", false); + registerCleanupFunction(do_cleanup); + + let which = "block_active"; + + SetupPrefTestEnvironment(which); + + for (let server of Object.keys(test_servers)) { + yield execute_test(server, test_settings[which].mimetype); + } + + SpecialPowers.popPrefEnv(); +}); diff --git a/dom/security/test/hsts/browser_hsts-priming_block_active_css.js b/dom/security/test/hsts/browser_hsts-priming_block_active_css.js new file mode 100644 index 000000000..340d11483 --- /dev/null +++ b/dom/security/test/hsts/browser_hsts-priming_block_active_css.js @@ -0,0 +1,24 @@ +/* + * Description of the test: + * Check that HSTS priming occurs correctly with mixed content when active + * content is blocked for css. + */ +'use strict'; + +//jscs:disable +add_task(function*() { + //jscs:enable + Services.obs.addObserver(Observer, "console-api-log-event", false); + Services.obs.addObserver(Observer, "http-on-examine-response", false); + registerCleanupFunction(do_cleanup); + + let which = "block_active_css"; + + SetupPrefTestEnvironment(which); + + for (let server of Object.keys(test_servers)) { + yield execute_test(server, test_settings[which].mimetype); + } + + SpecialPowers.popPrefEnv(); +}); diff --git a/dom/security/test/hsts/browser_hsts-priming_block_active_with_redir_same.js b/dom/security/test/hsts/browser_hsts-priming_block_active_with_redir_same.js new file mode 100644 index 000000000..130a3d5ec --- /dev/null +++ b/dom/security/test/hsts/browser_hsts-priming_block_active_with_redir_same.js @@ -0,0 +1,24 @@ +/* + * Description of the test: + * Check that HSTS priming occurs correctly with mixed content when active + * content is blocked and redirect to the same host should still upgrade. + */ +'use strict'; + +//jscs:disable +add_task(function*() { + //jscs:enable + Services.obs.addObserver(Observer, "console-api-log-event", false); + Services.obs.addObserver(Observer, "http-on-examine-response", false); + registerCleanupFunction(do_cleanup); + + let which = "block_active_with_redir_same"; + + SetupPrefTestEnvironment(which); + + for (let server of Object.keys(test_servers)) { + yield execute_test(server, test_settings[which].mimetype); + } + + SpecialPowers.popPrefEnv(); +}); diff --git a/dom/security/test/hsts/browser_hsts-priming_block_display.js b/dom/security/test/hsts/browser_hsts-priming_block_display.js new file mode 100644 index 000000000..4eca62718 --- /dev/null +++ b/dom/security/test/hsts/browser_hsts-priming_block_display.js @@ -0,0 +1,24 @@ +/* + * Description of the test: + * Check that HSTS priming occurs correctly with mixed content when display + * content is blocked. + */ +'use strict'; + +//jscs:disable +add_task(function*() { + //jscs:enable + Services.obs.addObserver(Observer, "console-api-log-event", false); + Services.obs.addObserver(Observer, "http-on-examine-response", false); + registerCleanupFunction(do_cleanup); + + let which = "block_display"; + + SetupPrefTestEnvironment(which); + + for (let server of Object.keys(test_servers)) { + yield execute_test(server, test_settings[which].mimetype); + } + + SpecialPowers.popPrefEnv(); +}); diff --git a/dom/security/test/hsts/browser_hsts-priming_cache-timeout.js b/dom/security/test/hsts/browser_hsts-priming_cache-timeout.js new file mode 100644 index 000000000..5416a71d2 --- /dev/null +++ b/dom/security/test/hsts/browser_hsts-priming_cache-timeout.js @@ -0,0 +1,36 @@ +/* + * Description of the test: + * Test that the network.hsts_priming.cache_timeout preferene causes the cache + * to timeout + */ +'use strict'; + +//jscs:disable +add_task(function*() { + //jscs:enable + Observer.add_observers(Services); + registerCleanupFunction(do_cleanup); + + let which = "block_display"; + + SetupPrefTestEnvironment(which, [["security.mixed_content.hsts_priming_cache_timeout", 1]]); + + yield execute_test("no-ssl", test_settings[which].mimetype); + + let pre_promise = performance.now(); + + while ((performance.now() - pre_promise) < 2000) { + yield new Promise(function (resolve) { + setTimeout(resolve, 2000); + }); + } + + // clear the fact that we saw a priming request + test_settings[which].priming = {}; + + yield execute_test("no-ssl", test_settings[which].mimetype); + is(test_settings[which].priming["no-ssl"], true, + "Correctly send a priming request after expiration."); + + SpecialPowers.popPrefEnv(); +}); diff --git a/dom/security/test/hsts/browser_hsts-priming_hsts_after_mixed.js b/dom/security/test/hsts/browser_hsts-priming_hsts_after_mixed.js new file mode 100644 index 000000000..89ea6fbeb --- /dev/null +++ b/dom/security/test/hsts/browser_hsts-priming_hsts_after_mixed.js @@ -0,0 +1,24 @@ +/* + * Description of the test: + * Check that HSTS priming occurs correctly with mixed content when the + * mixed-content blocks before HSTS. + */ +'use strict'; + +//jscs:disable +add_task(function*() { + //jscs:enable + Services.obs.addObserver(Observer, "console-api-log-event", false); + Services.obs.addObserver(Observer, "http-on-examine-response", false); + registerCleanupFunction(do_cleanup); + + let which = "hsts_after_mixed"; + + SetupPrefTestEnvironment(which); + + for (let server of Object.keys(test_servers)) { + yield execute_test(server, test_settings[which].mimetype); + } + + SpecialPowers.popPrefEnv(); +}); diff --git a/dom/security/test/hsts/browser_hsts-priming_no-duplicates.js b/dom/security/test/hsts/browser_hsts-priming_no-duplicates.js new file mode 100644 index 000000000..3846fe4f0 --- /dev/null +++ b/dom/security/test/hsts/browser_hsts-priming_no-duplicates.js @@ -0,0 +1,30 @@ +/* + * Description of the test: + * Only one request should be sent per host, even if we run the test more + * than once. + */ +'use strict'; + +//jscs:disable +add_task(function*() { + //jscs:enable + Observer.add_observers(Services); + registerCleanupFunction(do_cleanup); + + let which = "block_display"; + + SetupPrefTestEnvironment(which); + + for (let server of Object.keys(test_servers)) { + yield execute_test(server, test_settings[which].mimetype); + } + + test_settings[which].priming = {}; + + // run the tests twice to validate the cache is being used + for (let server of Object.keys(test_servers)) { + yield execute_test(server, test_settings[which].mimetype); + } + + SpecialPowers.popPrefEnv(); +}); diff --git a/dom/security/test/hsts/file_1x1.png b/dom/security/test/hsts/file_1x1.png new file mode 100644 index 000000000..1ba31ba1a Binary files /dev/null and b/dom/security/test/hsts/file_1x1.png differ diff --git a/dom/security/test/hsts/file_priming-top.html b/dom/security/test/hsts/file_priming-top.html new file mode 100644 index 000000000..b1d1bfa40 --- /dev/null +++ b/dom/security/test/hsts/file_priming-top.html @@ -0,0 +1,84 @@ + + + + Bug 1246540 + + + +

+ + + + + diff --git a/dom/security/test/hsts/file_priming.js b/dom/security/test/hsts/file_priming.js new file mode 100644 index 000000000..023022da6 --- /dev/null +++ b/dom/security/test/hsts/file_priming.js @@ -0,0 +1,4 @@ +function completed() { + return; +} +completed(); diff --git a/dom/security/test/hsts/file_stylesheet.css b/dom/security/test/hsts/file_stylesheet.css new file mode 100644 index 000000000..e69de29bb diff --git a/dom/security/test/hsts/file_testserver.sjs b/dom/security/test/hsts/file_testserver.sjs new file mode 100644 index 000000000..d5cd6b17a --- /dev/null +++ b/dom/security/test/hsts/file_testserver.sjs @@ -0,0 +1,66 @@ +// SJS file for HSTS mochitests + +Components.utils.import("resource://gre/modules/NetUtil.jsm"); +Components.utils.importGlobalProperties(["URLSearchParams"]); + +function loadFromFile(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 testFile = + Components.classes["@mozilla.org/file/directory_service;1"]. + getService(Components.interfaces.nsIProperties). + get("CurWorkD", Components.interfaces.nsILocalFile); + var dirs = path.split("/"); + for (var i = 0; i < dirs.length; i++) { + testFile.append(dirs[i]); + } + var testFileStream = + Components.classes["@mozilla.org/network/file-input-stream;1"]. + createInstance(Components.interfaces.nsIFileInputStream); + testFileStream.init(testFile, -1, 0, 0); + var test = NetUtil.readInputStreamToString(testFileStream, testFileStream.available()); + return test; +} + +function handleRequest(request, response) +{ + const query = new URLSearchParams(request.queryString); + + redir = query.get('redir'); + if (redir == 'same') { + query.delete("redir"); + response.setStatus(302); + let newURI = request.uri; + newURI.queryString = query.serialize(); + response.setHeader("Location", newURI.spec) + } + + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + // if we have a priming header, check for required behavior + // and set header appropriately + if (request.hasHeader('Upgrade-Insecure-Requests')) { + var expected = query.get('primer'); + if (expected == 'prime-hsts') { + // set it for 5 minutes + response.setHeader("Strict-Transport-Security", "max-age="+(60*5), false); + } else if (expected == 'reject-upgrade') { + response.setHeader("Strict-Transport-Security", "max-age=0", false); + } + response.write(''); + return; + } + + var file = query.get('file'); + if (file) { + var mimetype = unescape(query.get('mimetype')); + response.setHeader("Content-Type", mimetype, false); + response.write(loadFromFile(unescape(file))); + return; + } + + response.setHeader("Content-Type", "application/json", false); + response.write('{}'); +} diff --git a/dom/security/test/hsts/head.js b/dom/security/test/hsts/head.js new file mode 100644 index 000000000..362b36444 --- /dev/null +++ b/dom/security/test/hsts/head.js @@ -0,0 +1,308 @@ +/* + * Description of the tests: + * Check that HSTS priming occurs correctly with mixed content + * + * This test uses three hostnames, each of which treats an HSTS priming + * request differently. + * * no-ssl never returns an ssl response + * * reject-upgrade returns an ssl response, but with no STS header + * * prime-hsts returns an ssl response with the appropriate STS header + * + * For each server, test that it response appropriately when the we allow + * or block active or display content, as well as when we send an hsts priming + * request, but do not change the order of mixed-content and HSTS. + * + * Test use http-on-examine-response, so must be run in browser context. + */ +'use strict'; + +var TOP_URI = "https://example.com/browser/dom/security/test/hsts/file_priming-top.html"; + +var test_servers = { + // a test server that does not support TLS + 'no-ssl': { + host: 'example.co.jp', + response: false, + id: 'no-ssl', + }, + // a test server which does not support STS upgrade + 'reject-upgrade': { + host: 'example.org', + response: true, + id: 'reject-upgrade', + }, + // a test server when sends an STS header when priming + 'prime-hsts': { + host: 'test1.example.com', + response: true, + id: 'prime-hsts' + }, +}; + +var test_settings = { + // mixed active content is allowed, priming will upgrade + allow_active: { + block_active: false, + block_display: false, + use_hsts: true, + send_hsts_priming: true, + type: 'script', + result: { + 'no-ssl': 'insecure', + 'reject-upgrade': 'insecure', + 'prime-hsts': 'secure', + }, + }, + // mixed active content is blocked, priming will upgrade + block_active: { + block_active: true, + block_display: false, + use_hsts: true, + send_hsts_priming: true, + type: 'script', + result: { + 'no-ssl': 'blocked', + 'reject-upgrade': 'blocked', + 'prime-hsts': 'secure', + }, + }, + // keep the original order of mixed-content and HSTS, but send + // priming requests + hsts_after_mixed: { + block_active: true, + block_display: false, + use_hsts: false, + send_hsts_priming: true, + type: 'script', + result: { + 'no-ssl': 'blocked', + 'reject-upgrade': 'blocked', + 'prime-hsts': 'blocked', + }, + }, + // mixed display content is allowed, priming will upgrade + allow_display: { + block_active: true, + block_display: false, + use_hsts: true, + send_hsts_priming: true, + type: 'img', + result: { + 'no-ssl': 'insecure', + 'reject-upgrade': 'insecure', + 'prime-hsts': 'secure', + }, + }, + // mixed display content is blocked, priming will upgrade + block_display: { + block_active: true, + block_display: true, + use_hsts: true, + send_hsts_priming: true, + type: 'img', + result: { + 'no-ssl': 'blocked', + 'reject-upgrade': 'blocked', + 'prime-hsts': 'secure', + }, + }, + // mixed active content is blocked, priming will upgrade (css) + block_active_css: { + block_active: true, + block_display: false, + use_hsts: true, + send_hsts_priming: true, + type: 'css', + result: { + 'no-ssl': 'blocked', + 'reject-upgrade': 'blocked', + 'prime-hsts': 'secure', + }, + }, + // mixed active content is blocked, priming will upgrade + // redirect to the same host + block_active_with_redir_same: { + block_active: true, + block_display: false, + use_hsts: true, + send_hsts_priming: true, + type: 'script', + redir: 'same', + result: { + 'no-ssl': 'blocked', + 'reject-upgrade': 'blocked', + 'prime-hsts': 'secure', + }, + }, +} +// track which test we are on +var which_test = ""; + +const Observer = { + observe: function (subject, topic, data) { + switch (topic) { + case 'console-api-log-event': + return Observer.console_api_log_event(subject, topic, data); + case 'http-on-examine-response': + return Observer.http_on_examine_response(subject, topic, data); + case 'http-on-modify-request': + return Observer.http_on_modify_request(subject, topic, data); + } + throw "Can't handle topic "+topic; + }, + add_observers: function (services) { + services.obs.addObserver(Observer, "console-api-log-event", false); + services.obs.addObserver(Observer, "http-on-examine-response", false); + services.obs.addObserver(Observer, "http-on-modify-request", false); + }, + // When a load is blocked which results in an error event within a page, the + // test logs to the console. + console_api_log_event: function (subject, topic, data) { + var message = subject.wrappedJSObject.arguments[0]; + // when we are blocked, this will match the message we sent to the console, + // ignore everything else. + var re = RegExp(/^HSTS_PRIMING: Blocked ([-\w]+).*$/); + if (!re.test(message)) { + return; + } + + let id = message.replace(re, '$1'); + let curTest =test_servers[id]; + + if (!curTest) { + ok(false, "HSTS priming got a console message blocked, "+ + "but doesn't match expectations "+id+" (msg="+message); + return; + } + + is("blocked", test_settings[which_test].result[curTest.id], "HSTS priming "+ + which_test+":"+curTest.id+" expected "+ + test_settings[which_test].result[curTest.id]+", got blocked"); + test_settings[which_test].finished[curTest.id] = "blocked"; + }, + get_current_test: function(uri) { + for (let item in test_servers) { + let re = RegExp('https?://'+test_servers[item].host); + if (re.test(uri)) { + return test_servers[item]; + } + } + return null; + }, + http_on_modify_request: function (subject, topic, data) { + let channel = subject.QueryInterface(Ci.nsIHttpChannel); + if (channel.requestMethod != 'HEAD') { + return; + } + + let curTest = this.get_current_test(channel.URI.asciiSpec); + + if (!curTest) { + return; + } + + ok(!(curTest.id in test_settings[which_test].priming), "Already saw a priming request for " + curTest.id); + test_settings[which_test].priming[curTest.id] = true; + }, + // When we see a response come back, peek at the response and test it is secure + // or insecure as needed. Addtionally, watch the response for priming requests. + http_on_examine_response: function (subject, topic, data) { + let channel = subject.QueryInterface(Ci.nsIHttpChannel); + let curTest = this.get_current_test(channel.URI.asciiSpec); + + if (!curTest) { + return; + } + + let result = (channel.URI.asciiSpec.startsWith('https:')) ? "secure" : "insecure"; + + // This is a priming request, go ahead and validate we were supposed to see + // a response from the server + if (channel.requestMethod == 'HEAD') { + is(true, curTest.response, "HSTS priming response found " + curTest.id); + return; + } + + // This is the response to our query, make sure it matches + is(result, test_settings[which_test].result[curTest.id], + "HSTS priming result " + which_test + ":" + curTest.id); + test_settings[which_test].finished[curTest.id] = result; + }, +}; + +// opens `uri' in a new tab and focuses it. +// returns the newly opened tab +function openTab(uri) { + let tab = gBrowser.addTab(uri); + + // select tab and make sure its browser is focused + gBrowser.selectedTab = tab; + tab.ownerDocument.defaultView.focus(); + + return tab; +} + +function clear_sts_data() { + for (let test in test_servers) { + SpecialPowers.cleanUpSTSData('http://'+test_servers[test].host); + } +} + +function do_cleanup() { + clear_sts_data(); + + Services.obs.removeObserver(Observer, "console-api-log-event"); + Services.obs.removeObserver(Observer, "http-on-examine-response"); +} + +function SetupPrefTestEnvironment(which, additional_prefs) { + which_test = which; + clear_sts_data(); + + var settings = test_settings[which]; + // priming counts how many priming requests we saw + settings.priming = {}; + // priming counts how many tests were finished + settings.finished= {}; + + var prefs = [["security.mixed_content.block_active_content", + settings.block_active], + ["security.mixed_content.block_display_content", + settings.block_display], + ["security.mixed_content.use_hsts", + settings.use_hsts], + ["security.mixed_content.send_hsts_priming", + settings.send_hsts_priming]]; + + if (additional_prefs) { + for (let idx in additional_prefs) { + prefs.push(additional_prefs[idx]); + } + } + + console.log("prefs=%s", prefs); + + SpecialPowers.pushPrefEnv({'set': prefs}); +} + +// make the top-level test uri +function build_test_uri(base_uri, host, test_id, type) { + return base_uri + + "?host=" + escape(host) + + "&id=" + escape(test_id) + + "&type=" + escape(type); +} + +// open a new tab, load the test, and wait for it to finish +function execute_test(test, mimetype) { + var src = build_test_uri(TOP_URI, test_servers[test].host, + test, test_settings[which_test].type); + + let tab = openTab(src); + test_servers[test]['tab'] = tab; + + let browser = gBrowser.getBrowserForTab(tab); + yield BrowserTestUtils.browserLoaded(browser); + + yield BrowserTestUtils.removeTab(tab); +} diff --git a/dom/security/test/mixedcontentblocker/file_bug803225_test_mailto.html b/dom/security/test/mixedcontentblocker/file_bug803225_test_mailto.html new file mode 100644 index 000000000..f1459d366 --- /dev/null +++ b/dom/security/test/mixedcontentblocker/file_bug803225_test_mailto.html @@ -0,0 +1,13 @@ + + + + + + +Hello + + + diff --git a/dom/security/test/mixedcontentblocker/file_frameNavigation.html b/dom/security/test/mixedcontentblocker/file_frameNavigation.html new file mode 100644 index 000000000..fd9ea2317 --- /dev/null +++ b/dom/security/test/mixedcontentblocker/file_frameNavigation.html @@ -0,0 +1,74 @@ + + + + + + Tests for Mixed Content Frame Navigation + + +
+ + + + diff --git a/dom/security/test/mixedcontentblocker/file_frameNavigation_blankTarget.html b/dom/security/test/mixedcontentblocker/file_frameNavigation_blankTarget.html new file mode 100644 index 000000000..5cfd95984 --- /dev/null +++ b/dom/security/test/mixedcontentblocker/file_frameNavigation_blankTarget.html @@ -0,0 +1,32 @@ + + + + + + Tests for Mixed Content Frame Navigation + + +Go to http site + + + + diff --git a/dom/security/test/mixedcontentblocker/file_frameNavigation_grandchild.html b/dom/security/test/mixedcontentblocker/file_frameNavigation_grandchild.html new file mode 100644 index 000000000..1034991da --- /dev/null +++ b/dom/security/test/mixedcontentblocker/file_frameNavigation_grandchild.html @@ -0,0 +1,57 @@ + + + + + + Tests for Mixed Content Frame Navigation + + + + + + + diff --git a/dom/security/test/mixedcontentblocker/file_frameNavigation_innermost.html b/dom/security/test/mixedcontentblocker/file_frameNavigation_innermost.html new file mode 100644 index 000000000..62b24f37d --- /dev/null +++ b/dom/security/test/mixedcontentblocker/file_frameNavigation_innermost.html @@ -0,0 +1,72 @@ + + + +
+ + + diff --git a/dom/security/test/mixedcontentblocker/file_frameNavigation_secure.html b/dom/security/test/mixedcontentblocker/file_frameNavigation_secure.html new file mode 100644 index 000000000..ea8462c39 --- /dev/null +++ b/dom/security/test/mixedcontentblocker/file_frameNavigation_secure.html @@ -0,0 +1,73 @@ + + + + + + Tests for Mixed Content Frame Navigation + + +
+ + + + diff --git a/dom/security/test/mixedcontentblocker/file_frameNavigation_secure_grandchild.html b/dom/security/test/mixedcontentblocker/file_frameNavigation_secure_grandchild.html new file mode 100644 index 000000000..f7f3c4086 --- /dev/null +++ b/dom/security/test/mixedcontentblocker/file_frameNavigation_secure_grandchild.html @@ -0,0 +1,58 @@ + + + + + + Tests for Mixed Content Frame Navigation + + + + + + + diff --git a/dom/security/test/mixedcontentblocker/file_main.html b/dom/security/test/mixedcontentblocker/file_main.html new file mode 100644 index 000000000..ade5eefdb --- /dev/null +++ b/dom/security/test/mixedcontentblocker/file_main.html @@ -0,0 +1,261 @@ + + + + + + Tests for Bug 62178 + + + +
+ + + + + + diff --git a/dom/security/test/mixedcontentblocker/file_main_bug803225.html b/dom/security/test/mixedcontentblocker/file_main_bug803225.html new file mode 100644 index 000000000..e657be256 --- /dev/null +++ b/dom/security/test/mixedcontentblocker/file_main_bug803225.html @@ -0,0 +1,182 @@ + + + + + + Tests for Bug 62178 + + + +
+ + + + + + diff --git a/dom/security/test/mixedcontentblocker/file_main_bug803225_websocket_wsh.py b/dom/security/test/mixedcontentblocker/file_main_bug803225_websocket_wsh.py new file mode 100644 index 000000000..8c33c6b10 --- /dev/null +++ b/dom/security/test/mixedcontentblocker/file_main_bug803225_websocket_wsh.py @@ -0,0 +1,7 @@ +from mod_pywebsocket import msgutil + +def web_socket_do_extra_handshake(request): + pass + +def web_socket_transfer_data(request): + resp = "" diff --git a/dom/security/test/mixedcontentblocker/file_server.sjs b/dom/security/test/mixedcontentblocker/file_server.sjs new file mode 100644 index 000000000..58dffc565 --- /dev/null +++ b/dom/security/test/mixedcontentblocker/file_server.sjs @@ -0,0 +1,45 @@ + +function handleRequest(request, response) +{ + // get the Content-Type to serve from the query string + var contentType = null; + request.queryString.split('&').forEach( function (val) { + var [name, value] = val.split('='); + if (name == "type") { + contentType = unescape(value); + } + }); + + // avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + switch (contentType) { + case "iframe": + response.setHeader("Content-Type", "text/html", false); + response.write("frame content"); + break; + + case "script": + response.setHeader("Content-Type", "application/javascript", false); + break; + + case "stylesheet": + response.setHeader("Content-Type", "text/css", false); + break; + + case "object": + response.setHeader("Content-Type", "application/x-test", false); + break; + + case "xhr": + response.setHeader("Content-Type", "text/xml", false); + response.setHeader("Access-Control-Allow-Origin", "https://example.com"); + response.write(''); + break; + + default: + response.setHeader("Content-Type", "text/html", false); + response.write("Hello World"); + break; + } +} diff --git a/dom/security/test/mixedcontentblocker/mochitest.ini b/dom/security/test/mixedcontentblocker/mochitest.ini new file mode 100644 index 000000000..94c17f9b4 --- /dev/null +++ b/dom/security/test/mixedcontentblocker/mochitest.ini @@ -0,0 +1,23 @@ +[DEFAULT] +tags = mcb +support-files = + file_bug803225_test_mailto.html + file_frameNavigation.html + file_frameNavigation_blankTarget.html + file_frameNavigation_grandchild.html + file_frameNavigation_innermost.html + file_frameNavigation_secure.html + file_frameNavigation_secure_grandchild.html + file_main.html + file_main_bug803225.html + file_main_bug803225_websocket_wsh.py + file_server.sjs + !/dom/media/test/320x240.ogv + !/image/test/mochitest/blue.png + +[test_main.html] +skip-if = toolkit == 'android' #TIMED_OUT +[test_bug803225.html] +skip-if = toolkit == 'android' #TIMED_OUT +[test_frameNavigation.html] +skip-if = toolkit == 'android' #TIMED_OUT diff --git a/dom/security/test/mixedcontentblocker/test_bug803225.html b/dom/security/test/mixedcontentblocker/test_bug803225.html new file mode 100644 index 000000000..13c52762d --- /dev/null +++ b/dom/security/test/mixedcontentblocker/test_bug803225.html @@ -0,0 +1,152 @@ + + + + + + Tests for Bug 803225 + + + + + + + +
+

+
+
diff --git a/dom/security/test/mixedcontentblocker/test_frameNavigation.html b/dom/security/test/mixedcontentblocker/test_frameNavigation.html
new file mode 100644
index 000000000..5b3ae50b0
--- /dev/null
+++ b/dom/security/test/mixedcontentblocker/test_frameNavigation.html
@@ -0,0 +1,127 @@
+
+
+
+
+  
+  Tests for Bug 840388
+  
+  
+
+  
+
+
+
+  
+ +
+ +

+
+
diff --git a/dom/security/test/mixedcontentblocker/test_main.html b/dom/security/test/mixedcontentblocker/test_main.html
new file mode 100644
index 000000000..d2bc9dc7e
--- /dev/null
+++ b/dom/security/test/mixedcontentblocker/test_main.html
@@ -0,0 +1,187 @@
+
+
+
+
+  
+  Tests for Bug 62178
+  
+  
+
+  
+
+
+
+  
+

+
+
diff --git a/dom/security/test/moz.build b/dom/security/test/moz.build
new file mode 100644
index 000000000..ddb4e9b89
--- /dev/null
+++ b/dom/security/test/moz.build
@@ -0,0 +1,31 @@
+# -*- 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/.
+
+XPCSHELL_TESTS_MANIFESTS += [
+    'unit/xpcshell.ini',
+]
+
+TEST_DIRS += [
+    'gtest',
+]
+
+MOCHITEST_MANIFESTS += [
+    'cors/mochitest.ini',
+    'csp/mochitest.ini',
+    'general/mochitest.ini',
+    'mixedcontentblocker/mochitest.ini',
+    'sri/mochitest.ini',
+]
+
+MOCHITEST_CHROME_MANIFESTS += [
+    'general/chrome.ini',
+]
+
+BROWSER_CHROME_MANIFESTS += [
+    'contentverifier/browser.ini',
+    'csp/browser.ini',
+    'hsts/browser.ini',
+]
diff --git a/dom/security/test/sri/file_bug_1271796.css b/dom/security/test/sri/file_bug_1271796.css
new file mode 100644
index 000000000..c0928f2cf
--- /dev/null
+++ b/dom/security/test/sri/file_bug_1271796.css
@@ -0,0 +1,2 @@
+/*! Simple test for bug 1271796 */
+p::before { content: "\2014"; }
diff --git a/dom/security/test/sri/iframe_csp_directive_style_imports.html b/dom/security/test/sri/iframe_csp_directive_style_imports.html
new file mode 100644
index 000000000..0abea7854
--- /dev/null
+++ b/dom/security/test/sri/iframe_csp_directive_style_imports.html
@@ -0,0 +1,6 @@
+
+
+

blue text

diff --git a/dom/security/test/sri/iframe_csp_directive_style_imports.html^headers^ b/dom/security/test/sri/iframe_csp_directive_style_imports.html^headers^ new file mode 100644 index 000000000..0a6ccba79 --- /dev/null +++ b/dom/security/test/sri/iframe_csp_directive_style_imports.html^headers^ @@ -0,0 +1 @@ +content-security-policy: require-sri-for script style diff --git a/dom/security/test/sri/iframe_require-sri-for_main.html b/dom/security/test/sri/iframe_require-sri-for_main.html new file mode 100644 index 000000000..467c699c7 --- /dev/null +++ b/dom/security/test/sri/iframe_require-sri-for_main.html @@ -0,0 +1,47 @@ + + + + + + + + + + + + > + + + + + + + + + +

black text

+ diff --git a/dom/security/test/sri/iframe_require-sri-for_main.html^headers^ b/dom/security/test/sri/iframe_require-sri-for_main.html^headers^ new file mode 100644 index 000000000..0a6ccba79 --- /dev/null +++ b/dom/security/test/sri/iframe_require-sri-for_main.html^headers^ @@ -0,0 +1 @@ +content-security-policy: require-sri-for script style diff --git a/dom/security/test/sri/iframe_require-sri-for_no_csp.html b/dom/security/test/sri/iframe_require-sri-for_no_csp.html new file mode 100644 index 000000000..435b32ea3 --- /dev/null +++ b/dom/security/test/sri/iframe_require-sri-for_no_csp.html @@ -0,0 +1,5 @@ + diff --git a/dom/security/test/sri/iframe_script_crossdomain.html b/dom/security/test/sri/iframe_script_crossdomain.html new file mode 100644 index 000000000..a752c7e79 --- /dev/null +++ b/dom/security/test/sri/iframe_script_crossdomain.html @@ -0,0 +1,135 @@ + + + + + + + + +

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dom/security/test/sri/iframe_script_sameorigin.html b/dom/security/test/sri/iframe_script_sameorigin.html new file mode 100644 index 000000000..b891db547 --- /dev/null +++ b/dom/security/test/sri/iframe_script_sameorigin.html @@ -0,0 +1,249 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ +
+
+ + diff --git a/dom/security/test/sri/iframe_sri_disabled.html b/dom/security/test/sri/iframe_sri_disabled.html new file mode 100644 index 000000000..9fb10293a --- /dev/null +++ b/dom/security/test/sri/iframe_sri_disabled.html @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + +

+ +
+
+ + diff --git a/dom/security/test/sri/iframe_style_crossdomain.html b/dom/security/test/sri/iframe_style_crossdomain.html new file mode 100644 index 000000000..22c8593b5 --- /dev/null +++ b/dom/security/test/sri/iframe_style_crossdomain.html @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

This should be red but + this should be green and + this should be blue

+

+ +
+
+ + diff --git a/dom/security/test/sri/iframe_style_sameorigin.html b/dom/security/test/sri/iframe_style_sameorigin.html new file mode 100644 index 000000000..d994e7c2b --- /dev/null +++ b/dom/security/test/sri/iframe_style_sameorigin.html @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

This should be red , + this should be purple, + this should be brown, + this should be orange, and + this should be blue. + However, this should stay black and + this should also stay black. +

+ +

+ +
+
+ + diff --git a/dom/security/test/sri/mochitest.ini b/dom/security/test/sri/mochitest.ini new file mode 100644 index 000000000..e6e2e2fc3 --- /dev/null +++ b/dom/security/test/sri/mochitest.ini @@ -0,0 +1,57 @@ +[DEFAULT] +support-files = + file_bug_1271796.css + iframe_csp_directive_style_imports.html + iframe_csp_directive_style_imports.html^headers^ + iframe_require-sri-for_main.html + iframe_require-sri-for_main.html^headers^ + iframe_require-sri-for_no_csp.html + iframe_script_crossdomain.html + iframe_script_sameorigin.html + iframe_sri_disabled.html + iframe_style_crossdomain.html + iframe_style_sameorigin.html + rsf_csp_worker.js + rsf_csp_worker.js^headers^ + rsf_imported.js + rsf_worker.js + script_crossdomain1.js + script_crossdomain1.js^headers^ + script_crossdomain2.js + script_crossdomain3.js + script_crossdomain3.js^headers^ + script_crossdomain4.js + script_crossdomain4.js^headers^ + script_crossdomain5.js + script_crossdomain5.js^headers^ + script.js + script.js^headers^ + script_301.js + script_301.js^headers^ + script_302.js + script_302.js^headers^ + script_401.js + script_401.js^headers^ + style1.css + style1.css^headers^ + style2.css + style3.css + style4.css + style4.css^headers^ + style5.css + style6.css + style6.css^headers^ + style_301.css + style_301.css^headers^ + style_importing.css + style_imported.css + +[test_script_sameorigin.html] +[test_script_crossdomain.html] +[test_sri_disabled.html] +[test_style_crossdomain.html] +[test_style_sameorigin.html] +[test_require-sri-for_csp_directive.html] +[test_require-sri-for_csp_directive_disabled.html] +[test_bug_1271796.html] +[test_csp_directive_style_imports.html] diff --git a/dom/security/test/sri/rsf_csp_worker.js b/dom/security/test/sri/rsf_csp_worker.js new file mode 100644 index 000000000..553fdf92b --- /dev/null +++ b/dom/security/test/sri/rsf_csp_worker.js @@ -0,0 +1,9 @@ +postMessage("good_worker_could_load"); +try { + importScripts('rsf_imported.js'); +} catch(e) { + postMessage("good_worker_after_importscripts"); +} +finally { + postMessage("finish"); +} diff --git a/dom/security/test/sri/rsf_csp_worker.js^headers^ b/dom/security/test/sri/rsf_csp_worker.js^headers^ new file mode 100644 index 000000000..0a6ccba79 --- /dev/null +++ b/dom/security/test/sri/rsf_csp_worker.js^headers^ @@ -0,0 +1 @@ +content-security-policy: require-sri-for script style diff --git a/dom/security/test/sri/rsf_imported.js b/dom/security/test/sri/rsf_imported.js new file mode 100644 index 000000000..33f54b7a0 --- /dev/null +++ b/dom/security/test/sri/rsf_imported.js @@ -0,0 +1 @@ +postMessage('bad_worker_could_load_via_importScripts'); diff --git a/dom/security/test/sri/rsf_spawn_CSPd_worker.js b/dom/security/test/sri/rsf_spawn_CSPd_worker.js new file mode 100644 index 000000000..652c77100 --- /dev/null +++ b/dom/security/test/sri/rsf_spawn_CSPd_worker.js @@ -0,0 +1,3 @@ +w = new Worker("rsf_csp_worker.js"); +// use the handler function in test_require-sri-for_csp_directive.html +w.onmessage = parent.handler; diff --git a/dom/security/test/sri/rsf_worker.js b/dom/security/test/sri/rsf_worker.js new file mode 100644 index 000000000..553d3deee --- /dev/null +++ b/dom/security/test/sri/rsf_worker.js @@ -0,0 +1,2 @@ +parent.postMessage('bad_worker_could_load', '*'); +importScripts('rsf_imported.js'); diff --git a/dom/security/test/sri/script.js b/dom/security/test/sri/script.js new file mode 100644 index 000000000..8fd8f96b2 --- /dev/null +++ b/dom/security/test/sri/script.js @@ -0,0 +1 @@ +var load=true; diff --git a/dom/security/test/sri/script.js^headers^ b/dom/security/test/sri/script.js^headers^ new file mode 100644 index 000000000..b77232d81 --- /dev/null +++ b/dom/security/test/sri/script.js^headers^ @@ -0,0 +1 @@ +Cache-control: public diff --git a/dom/security/test/sri/script_301.js b/dom/security/test/sri/script_301.js new file mode 100644 index 000000000..9a95de77c --- /dev/null +++ b/dom/security/test/sri/script_301.js @@ -0,0 +1 @@ +var load=false; diff --git a/dom/security/test/sri/script_301.js^headers^ b/dom/security/test/sri/script_301.js^headers^ new file mode 100644 index 000000000..efbfb7334 --- /dev/null +++ b/dom/security/test/sri/script_301.js^headers^ @@ -0,0 +1,2 @@ +HTTP 301 Moved Permanently +Location: http://example.com/tests/dom/security/test/sri/script_crossdomain5.js diff --git a/dom/security/test/sri/script_302.js b/dom/security/test/sri/script_302.js new file mode 100644 index 000000000..9a95de77c --- /dev/null +++ b/dom/security/test/sri/script_302.js @@ -0,0 +1 @@ +var load=false; diff --git a/dom/security/test/sri/script_302.js^headers^ b/dom/security/test/sri/script_302.js^headers^ new file mode 100644 index 000000000..05a545a6a --- /dev/null +++ b/dom/security/test/sri/script_302.js^headers^ @@ -0,0 +1,2 @@ +HTTP 302 Found +Location: /tests/dom/security/test/sri/script.js diff --git a/dom/security/test/sri/script_401.js b/dom/security/test/sri/script_401.js new file mode 100644 index 000000000..8fd8f96b2 --- /dev/null +++ b/dom/security/test/sri/script_401.js @@ -0,0 +1 @@ +var load=true; diff --git a/dom/security/test/sri/script_401.js^headers^ b/dom/security/test/sri/script_401.js^headers^ new file mode 100644 index 000000000..889fbe081 --- /dev/null +++ b/dom/security/test/sri/script_401.js^headers^ @@ -0,0 +1,2 @@ +HTTP 401 Authorization Required +Cache-control: public diff --git a/dom/security/test/sri/script_crossdomain1.js b/dom/security/test/sri/script_crossdomain1.js new file mode 100644 index 000000000..1f17a6db2 --- /dev/null +++ b/dom/security/test/sri/script_crossdomain1.js @@ -0,0 +1,4 @@ +/* + * this file should be loaded, because it has CORS enabled. +*/ +window.hasCORSLoaded = true; diff --git a/dom/security/test/sri/script_crossdomain1.js^headers^ b/dom/security/test/sri/script_crossdomain1.js^headers^ new file mode 100644 index 000000000..3a6a85d89 --- /dev/null +++ b/dom/security/test/sri/script_crossdomain1.js^headers^ @@ -0,0 +1 @@ +Access-Control-Allow-Origin: http://mochi.test:8888 diff --git a/dom/security/test/sri/script_crossdomain2.js b/dom/security/test/sri/script_crossdomain2.js new file mode 100644 index 000000000..4b0208ab3 --- /dev/null +++ b/dom/security/test/sri/script_crossdomain2.js @@ -0,0 +1,5 @@ +/* + * this file should not be loaded, because it does not have CORS + * enabled. + */ +window.hasNonCORSLoaded = true; diff --git a/dom/security/test/sri/script_crossdomain3.js b/dom/security/test/sri/script_crossdomain3.js new file mode 100644 index 000000000..eed05d59b --- /dev/null +++ b/dom/security/test/sri/script_crossdomain3.js @@ -0,0 +1 @@ +// This script intentionally left blank diff --git a/dom/security/test/sri/script_crossdomain3.js^headers^ b/dom/security/test/sri/script_crossdomain3.js^headers^ new file mode 100644 index 000000000..3a6a85d89 --- /dev/null +++ b/dom/security/test/sri/script_crossdomain3.js^headers^ @@ -0,0 +1 @@ +Access-Control-Allow-Origin: http://mochi.test:8888 diff --git a/dom/security/test/sri/script_crossdomain4.js b/dom/security/test/sri/script_crossdomain4.js new file mode 100644 index 000000000..eed05d59b --- /dev/null +++ b/dom/security/test/sri/script_crossdomain4.js @@ -0,0 +1 @@ +// This script intentionally left blank diff --git a/dom/security/test/sri/script_crossdomain4.js^headers^ b/dom/security/test/sri/script_crossdomain4.js^headers^ new file mode 100644 index 000000000..3a6a85d89 --- /dev/null +++ b/dom/security/test/sri/script_crossdomain4.js^headers^ @@ -0,0 +1 @@ +Access-Control-Allow-Origin: http://mochi.test:8888 diff --git a/dom/security/test/sri/script_crossdomain5.js b/dom/security/test/sri/script_crossdomain5.js new file mode 100644 index 000000000..eed05d59b --- /dev/null +++ b/dom/security/test/sri/script_crossdomain5.js @@ -0,0 +1 @@ +// This script intentionally left blank diff --git a/dom/security/test/sri/script_crossdomain5.js^headers^ b/dom/security/test/sri/script_crossdomain5.js^headers^ new file mode 100644 index 000000000..cb762eff8 --- /dev/null +++ b/dom/security/test/sri/script_crossdomain5.js^headers^ @@ -0,0 +1 @@ +Access-Control-Allow-Origin: * diff --git a/dom/security/test/sri/style1.css b/dom/security/test/sri/style1.css new file mode 100644 index 000000000..c7ab9ecff --- /dev/null +++ b/dom/security/test/sri/style1.css @@ -0,0 +1,3 @@ +#red-text { + color: red; +} diff --git a/dom/security/test/sri/style1.css^headers^ b/dom/security/test/sri/style1.css^headers^ new file mode 100644 index 000000000..3a6a85d89 --- /dev/null +++ b/dom/security/test/sri/style1.css^headers^ @@ -0,0 +1 @@ +Access-Control-Allow-Origin: http://mochi.test:8888 diff --git a/dom/security/test/sri/style2.css b/dom/security/test/sri/style2.css new file mode 100644 index 000000000..9eece75e5 --- /dev/null +++ b/dom/security/test/sri/style2.css @@ -0,0 +1 @@ +; A valid but somewhat uninteresting stylesheet diff --git a/dom/security/test/sri/style3.css b/dom/security/test/sri/style3.css new file mode 100644 index 000000000..b64fa3b74 --- /dev/null +++ b/dom/security/test/sri/style3.css @@ -0,0 +1,3 @@ +#black-text { + color: green; +} diff --git a/dom/security/test/sri/style4.css b/dom/security/test/sri/style4.css new file mode 100644 index 000000000..eab83656e --- /dev/null +++ b/dom/security/test/sri/style4.css @@ -0,0 +1,4 @@ +/* François was here. */ +#purple-text { + color: purple; +} diff --git a/dom/security/test/sri/style4.css^headers^ b/dom/security/test/sri/style4.css^headers^ new file mode 100644 index 000000000..e13897f15 --- /dev/null +++ b/dom/security/test/sri/style4.css^headers^ @@ -0,0 +1 @@ +Content-Type: text/css; charset=utf-8 diff --git a/dom/security/test/sri/style5.css b/dom/security/test/sri/style5.css new file mode 100644 index 000000000..5d59134cc --- /dev/null +++ b/dom/security/test/sri/style5.css @@ -0,0 +1,4 @@ +/* François was here. */ +#orange-text { + color: orange; +} diff --git a/dom/security/test/sri/style6.css b/dom/security/test/sri/style6.css new file mode 100644 index 000000000..569557694 --- /dev/null +++ b/dom/security/test/sri/style6.css @@ -0,0 +1,4 @@ +/* François was here. */ +#brown-text { + color: brown; +} diff --git a/dom/security/test/sri/style6.css^headers^ b/dom/security/test/sri/style6.css^headers^ new file mode 100644 index 000000000..d866aa522 --- /dev/null +++ b/dom/security/test/sri/style6.css^headers^ @@ -0,0 +1 @@ +Content-Type: text/css; charset=iso-8859-8 diff --git a/dom/security/test/sri/style_301.css b/dom/security/test/sri/style_301.css new file mode 100644 index 000000000..c7ab9ecff --- /dev/null +++ b/dom/security/test/sri/style_301.css @@ -0,0 +1,3 @@ +#red-text { + color: red; +} diff --git a/dom/security/test/sri/style_301.css^headers^ b/dom/security/test/sri/style_301.css^headers^ new file mode 100644 index 000000000..c5b78ee04 --- /dev/null +++ b/dom/security/test/sri/style_301.css^headers^ @@ -0,0 +1,2 @@ +HTTP 301 Moved Permanently +Location: http://example.com/tests/dom/security/test/sri/style1.css diff --git a/dom/security/test/sri/style_imported.css b/dom/security/test/sri/style_imported.css new file mode 100644 index 000000000..4469e8d78 --- /dev/null +++ b/dom/security/test/sri/style_imported.css @@ -0,0 +1,6 @@ +#text-for-import-test { + color: red; +} +#text-for-import-test::before { + content: 'Test failed'; +} diff --git a/dom/security/test/sri/style_importing.css b/dom/security/test/sri/style_importing.css new file mode 100644 index 000000000..985dd3467 --- /dev/null +++ b/dom/security/test/sri/style_importing.css @@ -0,0 +1,4 @@ +/* neither of them should load. trying multiple cases*/ +@import url("style_imported.css"); +@import 'style_imported.css'; +#text-for-import-test { color: blue; } diff --git a/dom/security/test/sri/test_bug_1271796.html b/dom/security/test/sri/test_bug_1271796.html new file mode 100644 index 000000000..1d639c9cb --- /dev/null +++ b/dom/security/test/sri/test_bug_1271796.html @@ -0,0 +1,30 @@ + + + + + + + + + + +Bug 1271796
+

This text is prepended by emdash if css has loaded

+ + diff --git a/dom/security/test/sri/test_csp_directive_style_imports.html b/dom/security/test/sri/test_csp_directive_style_imports.html new file mode 100644 index 000000000..f293e2412 --- /dev/null +++ b/dom/security/test/sri/test_csp_directive_style_imports.html @@ -0,0 +1,42 @@ + + + + + Test for SRI require-sri-for CSP directive + + + + +Mozilla Bug 1265318
+
+ + + diff --git a/dom/security/test/sri/test_require-sri-for_csp_directive.html b/dom/security/test/sri/test_require-sri-for_csp_directive.html new file mode 100644 index 000000000..ef1b3603f --- /dev/null +++ b/dom/security/test/sri/test_require-sri-for_csp_directive.html @@ -0,0 +1,76 @@ + + + + + Test for SRI require-sri-for CSP directive + + + + +Mozilla Bug 1265318
+
+ + + + diff --git a/dom/security/test/sri/test_require-sri-for_csp_directive_disabled.html b/dom/security/test/sri/test_require-sri-for_csp_directive_disabled.html new file mode 100644 index 000000000..b833fe11c --- /dev/null +++ b/dom/security/test/sri/test_require-sri-for_csp_directive_disabled.html @@ -0,0 +1,46 @@ + + + + + Test for diabled SRI require-sri-for CSP directive + + + + +Mozilla Bug 1265318 + + + + diff --git a/dom/security/test/sri/test_script_crossdomain.html b/dom/security/test/sri/test_script_crossdomain.html new file mode 100644 index 000000000..327ea4247 --- /dev/null +++ b/dom/security/test/sri/test_script_crossdomain.html @@ -0,0 +1,18 @@ + + + + + + Cross-domain script tests for Bug 992096 + + + +Mozilla Bug 992096 +
+ +
+ + diff --git a/dom/security/test/sri/test_script_sameorigin.html b/dom/security/test/sri/test_script_sameorigin.html new file mode 100644 index 000000000..df890d5f9 --- /dev/null +++ b/dom/security/test/sri/test_script_sameorigin.html @@ -0,0 +1,18 @@ + + + + + + Same-origin script tests for Bug 992096 + + + +Mozilla Bug 992096 +
+ +
+ + diff --git a/dom/security/test/sri/test_sri_disabled.html b/dom/security/test/sri/test_sri_disabled.html new file mode 100644 index 000000000..4661235b1 --- /dev/null +++ b/dom/security/test/sri/test_sri_disabled.html @@ -0,0 +1,18 @@ + + + + + + security.sri.enable tests for Bug 992096 + + + +Mozilla Bug 992096 +
+ +
+ + diff --git a/dom/security/test/sri/test_style_crossdomain.html b/dom/security/test/sri/test_style_crossdomain.html new file mode 100644 index 000000000..6bf4b2de1 --- /dev/null +++ b/dom/security/test/sri/test_style_crossdomain.html @@ -0,0 +1,18 @@ + + + + + + Cross-domain stylesheet tests for Bug 1196740 + + + +Mozilla Bug 1196740 +
+ +
+ + diff --git a/dom/security/test/sri/test_style_sameorigin.html b/dom/security/test/sri/test_style_sameorigin.html new file mode 100644 index 000000000..fb1d3f78d --- /dev/null +++ b/dom/security/test/sri/test_style_sameorigin.html @@ -0,0 +1,18 @@ + + + + + + Same-origin stylesheet tests for Bug 992096 + + + +Mozilla Bug 992096 +
+ +
+ + diff --git a/dom/security/test/unit/test_csp_reports.js b/dom/security/test/unit/test_csp_reports.js new file mode 100644 index 000000000..6c88fb1e1 --- /dev/null +++ b/dom/security/test/unit/test_csp_reports.js @@ -0,0 +1,231 @@ +/* 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/. */ + +var Cc = Components.classes; +var Ci = Components.interfaces; +var Cu = Components.utils; +var Cr = Components.results; + +Cu.import('resource://gre/modules/NetUtil.jsm'); +Cu.import("resource://gre/modules/Services.jsm"); +Cu.import("resource://testing-common/httpd.js"); + +var httpServer = new HttpServer(); +httpServer.start(-1); +var testsToFinish = 0; + +var principal; + +const REPORT_SERVER_PORT = httpServer.identity.primaryPort; +const REPORT_SERVER_URI = "http://localhost"; +const REPORT_SERVER_PATH = "/report"; + +/** + * Construct a callback that listens to a report submission and either passes + * or fails a test based on what it gets. + */ +function makeReportHandler(testpath, message, expectedJSON) { + return function(request, response) { + // we only like "POST" submissions for reports! + if (request.method !== "POST") { + do_throw("violation report should be a POST request"); + return; + } + + // check content-type of report is "application/csp-report" + var contentType = request.hasHeader("Content-Type") + ? request.getHeader("Content-Type") : undefined; + if (contentType !== "application/csp-report") { + do_throw("violation report should have the 'application/csp-report' " + + "content-type, when in fact it is " + contentType.toString()) + } + + // obtain violation report + var reportObj = JSON.parse( + NetUtil.readInputStreamToString( + request.bodyInputStream, + request.bodyInputStream.available())); + + // dump("GOT REPORT:\n" + JSON.stringify(reportObj) + "\n"); + // dump("TESTPATH: " + testpath + "\n"); + // dump("EXPECTED: \n" + JSON.stringify(expectedJSON) + "\n\n"); + + for (var i in expectedJSON) + do_check_eq(expectedJSON[i], reportObj['csp-report'][i]); + + testsToFinish--; + httpServer.registerPathHandler(testpath, null); + if (testsToFinish < 1) + httpServer.stop(do_test_finished); + else + do_test_finished(); + }; +} + +/** + * Everything created by this assumes it will cause a report. If you want to + * add a test here that will *not* cause a report to go out, you're gonna have + * to make sure the test cleans up after itself. + */ +function makeTest(id, expectedJSON, useReportOnlyPolicy, callback) { + testsToFinish++; + do_test_pending(); + + // set up a new CSP instance for each test. + var csp = Cc["@mozilla.org/cspcontext;1"] + .createInstance(Ci.nsIContentSecurityPolicy); + var policy = "default-src 'none'; " + + "report-uri " + REPORT_SERVER_URI + + ":" + REPORT_SERVER_PORT + + "/test" + id; + var selfuri = NetUtil.newURI(REPORT_SERVER_URI + + ":" + REPORT_SERVER_PORT + + "/foo/self"); + + dump("Created test " + id + " : " + policy + "\n\n"); + + let ssm = Cc["@mozilla.org/scriptsecuritymanager;1"] + .getService(Ci.nsIScriptSecurityManager); + principal = ssm.createCodebasePrincipal(selfuri, {}); + csp.setRequestContext(null, principal); + + // Load up the policy + // set as report-only if that's the case + csp.appendPolicy(policy, useReportOnlyPolicy, false); + + // prime the report server + var handler = makeReportHandler("/test" + id, "Test " + id, expectedJSON); + httpServer.registerPathHandler("/test" + id, handler); + + //trigger the violation + callback(csp); +} + +function run_test() { + var selfuri = NetUtil.newURI(REPORT_SERVER_URI + + ":" + REPORT_SERVER_PORT + + "/foo/self"); + + // test that inline script violations cause a report. + makeTest(0, {"blocked-uri": "self"}, false, + function(csp) { + let inlineOK = true; + inlineOK = csp.getAllowsInline(Ci.nsIContentPolicy.TYPE_SCRIPT, + "", // aNonce + false, // aParserCreated + "", // aContent + 0); // aLineNumber + + // this is not a report only policy, so it better block inline scripts + do_check_false(inlineOK); + }); + + // test that eval violations cause a report. + makeTest(1, {"blocked-uri": "self", + // JSON script-sample is UTF8 encoded + "script-sample" : "\xc2\xa3\xc2\xa5\xc2\xb5\xe5\x8c\x97\xf0\xa0\x9d\xb9"}, false, + function(csp) { + let evalOK = true, oReportViolation = {'value': false}; + evalOK = csp.getAllowsEval(oReportViolation); + + // this is not a report only policy, so it better block eval + do_check_false(evalOK); + // ... and cause reports to go out + do_check_true(oReportViolation.value); + + if (oReportViolation.value) { + // force the logging, since the getter doesn't. + csp.logViolationDetails(Ci.nsIContentSecurityPolicy.VIOLATION_TYPE_EVAL, + selfuri.asciiSpec, + // sending UTF-16 script sample to make sure + // csp report in JSON is not cut-off, please + // note that JSON is UTF8 encoded. + "\u00a3\u00a5\u00b5\u5317\ud841\udf79", + 1); + } + }); + + makeTest(2, {"blocked-uri": "http://blocked.test"}, false, + function(csp) { + // shouldLoad creates and sends out the report here. + csp.shouldLoad(Ci.nsIContentPolicy.TYPE_SCRIPT, + NetUtil.newURI("http://blocked.test/foo.js"), + null, null, null, null); + }); + + // test that inline script violations cause a report in report-only policy + makeTest(3, {"blocked-uri": "self"}, true, + function(csp) { + let inlineOK = true; + inlineOK = csp.getAllowsInline(Ci.nsIContentPolicy.TYPE_SCRIPT, + "", // aNonce + false, // aParserCreated + "", // aContent + 0); // aLineNumber + + // this is a report only policy, so it better allow inline scripts + do_check_true(inlineOK); + }); + + // test that eval violations cause a report in report-only policy + makeTest(4, {"blocked-uri": "self"}, true, + function(csp) { + let evalOK = true, oReportViolation = {'value': false}; + evalOK = csp.getAllowsEval(oReportViolation); + + // this is a report only policy, so it better allow eval + do_check_true(evalOK); + // ... but still cause reports to go out + do_check_true(oReportViolation.value); + + if (oReportViolation.value) { + // force the logging, since the getter doesn't. + csp.logViolationDetails(Ci.nsIContentSecurityPolicy.VIOLATION_TYPE_INLINE_SCRIPT, + selfuri.asciiSpec, + "script sample", + 4); + } + }); + + // test that only the uri's scheme is reported for globally unique identifiers + makeTest(5, {"blocked-uri": "data"}, false, + function(csp) { + var base64data = + "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12" + + "P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="; + // shouldLoad creates and sends out the report here. + csp.shouldLoad(Ci.nsIContentPolicy.TYPE_IMAGE, + NetUtil.newURI("data:image/png;base64," + base64data), + null, null, null, null); + }); + + // test that only the uri's scheme is reported for globally unique identifiers + makeTest(6, {"blocked-uri": "intent"}, false, + function(csp) { + // shouldLoad creates and sends out the report here. + csp.shouldLoad(Ci.nsIContentPolicy.TYPE_SUBDOCUMENT, + NetUtil.newURI("intent://mymaps.com/maps?um=1&ie=UTF-8&fb=1&sll"), + null, null, null, null); + }); + + // test fragment removal + var selfSpec = REPORT_SERVER_URI + ":" + REPORT_SERVER_PORT + "/foo/self/foo.js"; + makeTest(7, {"blocked-uri": selfSpec}, false, + function(csp) { + var uri = NetUtil + // shouldLoad creates and sends out the report here. + csp.shouldLoad(Ci.nsIContentPolicy.TYPE_SCRIPT, + NetUtil.newURI(selfSpec + "#bar"), + null, null, null, null); + }); + + // test scheme of ftp: + makeTest(8, {"blocked-uri": "ftp://blocked.test"}, false, + function(csp) { + // shouldLoad creates and sends out the report here. + csp.shouldLoad(Ci.nsIContentPolicy.TYPE_SCRIPT, + NetUtil.newURI("ftp://blocked.test/profile.png"), + null, null, null, null); + }); +} diff --git a/dom/security/test/unit/test_csp_upgrade_insecure_request_header.js b/dom/security/test/unit/test_csp_upgrade_insecure_request_header.js new file mode 100644 index 000000000..8be873234 --- /dev/null +++ b/dom/security/test/unit/test_csp_upgrade_insecure_request_header.js @@ -0,0 +1,107 @@ +var Cu = Components.utils; +var Ci = Components.interfaces; +var Cc = Components.classes; + +Cu.import("resource://testing-common/httpd.js"); +Cu.import("resource://gre/modules/NetUtil.jsm"); +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); + +var prefs = Cc["@mozilla.org/preferences-service;1"]. + getService(Ci.nsIPrefBranch); + +// Since this test creates a TYPE_DOCUMENT channel via javascript, it will +// end up using the wrong LoadInfo constructor. Setting this pref will disable +// the ContentPolicyType assertion in the constructor. +prefs.setBoolPref("network.loadinfo.skip_type_assertion", true); + +XPCOMUtils.defineLazyGetter(this, "URL", function() { + return "http://localhost:" + httpserver.identity.primaryPort; +}); + +var httpserver = null; +var channel = null; +var curTest = null; +var testpath = "/footpath"; + +var tests = [ + { + description: "should not set request header for TYPE_OTHER", + expectingHeader: false, + contentType: Ci.nsIContentPolicy.TYPE_OTHER + }, + { + description: "should set request header for TYPE_DOCUMENT", + expectingHeader: true, + contentType: Ci.nsIContentPolicy.TYPE_DOCUMENT + }, + { + description: "should set request header for TYPE_SUBDOCUMENT", + expectingHeader: true, + contentType: Ci.nsIContentPolicy.TYPE_SUBDOCUMENT + }, + { + description: "should not set request header for TYPE_IMG", + expectingHeader: false, + contentType: Ci.nsIContentPolicy.TYPE_IMG + }, +]; + +function ChannelListener() { +} + +ChannelListener.prototype = { + onStartRequest: function(request, context) { }, + onDataAvailable: function(request, context, stream, offset, count) { + do_throw("Should not get any data!"); + }, + onStopRequest: function(request, context, status) { + var upgrade_insecure_header = false; + try { + if (request.getRequestHeader("Upgrade-Insecure-Requests")) { + upgrade_insecure_header = true; + } + } + catch (e) { + // exception is thrown if header is not available on the request + } + // debug + // dump("executing test: " + curTest.description); + do_check_eq(upgrade_insecure_header, curTest.expectingHeader) + run_next_test(); + }, +}; + +function setupChannel(aContentType) { + var chan = NetUtil.newChannel({ + uri: URL + testpath, + loadUsingSystemPrincipal: true, + contentPolicyType: aContentType + }); + chan.QueryInterface(Ci.nsIHttpChannel); + chan.requestMethod = "GET"; + return chan; +} + +function serverHandler(metadata, response) { + // no need to perform anything here +} + +function run_next_test() { + curTest = tests.shift(); + if (!curTest) { + httpserver.stop(do_test_finished); + return; + } + channel = setupChannel(curTest.contentType); + channel.asyncOpen2(new ChannelListener()); +} + +function run_test() { + // set up the test environment + httpserver = new HttpServer(); + httpserver.registerPathHandler(testpath, serverHandler); + httpserver.start(-1); + + run_next_test(); + do_test_pending(); +} diff --git a/dom/security/test/unit/test_isOriginPotentiallyTrustworthy.js b/dom/security/test/unit/test_isOriginPotentiallyTrustworthy.js new file mode 100644 index 000000000..7de8faa8f --- /dev/null +++ b/dom/security/test/unit/test_isOriginPotentiallyTrustworthy.js @@ -0,0 +1,47 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/* + * Tests the "Is origin potentially trustworthy?" logic from + * . + */ + +const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; + +Cu.import("resource://gre/modules/NetUtil.jsm"); +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); + +XPCOMUtils.defineLazyServiceGetter(this, "gScriptSecurityManager", + "@mozilla.org/scriptsecuritymanager;1", + "nsIScriptSecurityManager"); + +XPCOMUtils.defineLazyServiceGetter(this, "gContentSecurityManager", + "@mozilla.org/contentsecuritymanager;1", + "nsIContentSecurityManager"); + +var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch); +prefs.setCharPref("dom.securecontext.whitelist", "example.net,example.org"); + +add_task(function* test_isOriginPotentiallyTrustworthy() { + for (let [uriSpec, expectedResult] of [ + ["http://example.com/", false], + ["https://example.com/", true], + ["http://localhost/", true], + ["http://127.0.0.1/", true], + ["file:///", true], + ["resource:///", true], + ["app://", true], + ["moz-extension://", true], + ["wss://example.com/", true], + ["about:config", false], + ["urn:generic", false], + ["http://example.net/", true], + ["ws://example.org/", true], + ["chrome://example.net/content/messenger.xul", false], + ]) { + let uri = NetUtil.newURI(uriSpec); + let principal = gScriptSecurityManager.getCodebasePrincipal(uri); + Assert.equal(gContentSecurityManager.isOriginPotentiallyTrustworthy(principal), + expectedResult); + } +}); diff --git a/dom/security/test/unit/xpcshell.ini b/dom/security/test/unit/xpcshell.ini new file mode 100644 index 000000000..7e1d4a0ed --- /dev/null +++ b/dom/security/test/unit/xpcshell.ini @@ -0,0 +1,7 @@ +[DEFAULT] +head = +tail = + +[test_csp_reports.js] +[test_isOriginPotentiallyTrustworthy.js] +[test_csp_upgrade_insecure_request_header.js] -- cgit v1.2.3