browser_webconsole_hpkp_invalid-headers.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
  2. /* Any copyright is dedicated to the Public Domain.
  3. * http://creativecommons.org/publicdomain/zero/1.0/ */
  4. // Tests that errors about invalid HPKP security headers are logged to the web
  5. // console.
  6. "use strict";
  7. const TEST_URI = "data:text/html;charset=utf-8,Web Console HPKP invalid " +
  8. "header test";
  9. const SJS_URL = "https://example.com/browser/devtools/client/webconsole/" +
  10. "test/test_hpkp-invalid-headers.sjs";
  11. const LEARN_MORE_URI = "https://developer.mozilla.org/docs/Web/Security/" +
  12. "Public_Key_Pinning" + DOCS_GA_PARAMS;
  13. const HPKP_ENABLED_PREF = "security.cert_pinning.hpkp.enabled";
  14. const NON_BUILTIN_ROOT_PREF = "security.cert_pinning.process_headers_from_" +
  15. "non_builtin_roots";
  16. add_task(function* () {
  17. registerCleanupFunction(() => {
  18. Services.prefs.clearUserPref(HPKP_ENABLED_PREF);
  19. Services.prefs.clearUserPref(NON_BUILTIN_ROOT_PREF);
  20. });
  21. Services.prefs.setBoolPref(HPKP_ENABLED_PREF, true);
  22. yield loadTab(TEST_URI);
  23. let hud = yield openConsole();
  24. yield* checkForMessage({
  25. url: SJS_URL + "?badSyntax",
  26. name: "Could not parse header error displayed successfully",
  27. text: "Public-Key-Pins: The site specified a header that could not be " +
  28. "parsed successfully."
  29. }, hud);
  30. yield* checkForMessage({
  31. url: SJS_URL + "?noMaxAge",
  32. name: "No max-age error displayed successfully",
  33. text: "Public-Key-Pins: The site specified a header that did not include " +
  34. "a \u2018max-age\u2019 directive."
  35. }, hud);
  36. yield* checkForMessage({
  37. url: SJS_URL + "?invalidIncludeSubDomains",
  38. name: "Invalid includeSubDomains error displayed successfully",
  39. text: "Public-Key-Pins: The site specified a header that included an " +
  40. "invalid \u2018includeSubDomains\u2019 directive."
  41. }, hud);
  42. yield* checkForMessage({
  43. url: SJS_URL + "?invalidMaxAge",
  44. name: "Invalid max-age error displayed successfully",
  45. text: "Public-Key-Pins: The site specified a header that included an " +
  46. "invalid \u2018max-age\u2019 directive."
  47. }, hud);
  48. yield* checkForMessage({
  49. url: SJS_URL + "?multipleIncludeSubDomains",
  50. name: "Multiple includeSubDomains error displayed successfully",
  51. text: "Public-Key-Pins: The site specified a header that included " +
  52. "multiple \u2018includeSubDomains\u2019 directives."
  53. }, hud);
  54. yield* checkForMessage({
  55. url: SJS_URL + "?multipleMaxAge",
  56. name: "Multiple max-age error displayed successfully",
  57. text: "Public-Key-Pins: The site specified a header that included " +
  58. "multiple \u2018max-age\u2019 directives."
  59. }, hud);
  60. yield* checkForMessage({
  61. url: SJS_URL + "?multipleReportURIs",
  62. name: "Multiple report-uri error displayed successfully",
  63. text: "Public-Key-Pins: The site specified a header that included " +
  64. "multiple \u2018report-uri\u2019 directives."
  65. }, hud);
  66. // The root used for mochitests is not built-in, so set the relevant pref to
  67. // true to have the PKP implementation return more specific errors.
  68. Services.prefs.setBoolPref(NON_BUILTIN_ROOT_PREF, true);
  69. yield* checkForMessage({
  70. url: SJS_URL + "?pinsetDoesNotMatch",
  71. name: "Non-matching pinset error displayed successfully",
  72. text: "Public-Key-Pins: The site specified a header that did not include " +
  73. "a matching pin."
  74. }, hud);
  75. Services.prefs.setBoolPref(NON_BUILTIN_ROOT_PREF, false);
  76. yield* checkForMessage({
  77. url: SJS_URL + "?pinsetDoesNotMatch",
  78. name: "Non-built-in root error displayed successfully",
  79. text: "Public-Key-Pins: The certificate used by the site was not issued " +
  80. "by a certificate in the default root certificate store. To " +
  81. "prevent accidental breakage, the specified header was ignored."
  82. }, hud);
  83. });
  84. function* checkForMessage(curTest, hud) {
  85. hud.jsterm.clearOutput();
  86. BrowserTestUtils.loadURI(gBrowser.selectedBrowser, curTest.url);
  87. let results = yield waitForMessages({
  88. webconsole: hud,
  89. messages: [
  90. {
  91. name: curTest.name,
  92. text: curTest.text,
  93. category: CATEGORY_SECURITY,
  94. severity: SEVERITY_WARNING,
  95. objects: true,
  96. },
  97. ],
  98. });
  99. yield testClickOpenNewTab(hud, results);
  100. }
  101. function testClickOpenNewTab(hud, results) {
  102. let warningNode = results[0].clickableElements[0];
  103. ok(warningNode, "link element");
  104. ok(warningNode.classList.contains("learn-more-link"), "link class name");
  105. return simulateMessageLinkClick(warningNode, LEARN_MORE_URI);
  106. }