forked from Floorp-Projects/Floorp
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Bug 1620242 - Basic implementation for HTTPS Only Mode. r=ckerschb,mi…
…xedpuppy Differential Revision: https://phabricator.services.mozilla.com/D62590
- Loading branch information
1 parent
b640ef2
commit ae075b2
Showing
29 changed files
with
796 additions
and
58 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
/* -*- 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 "mozilla/StaticPrefs_dom.h" | ||
#include "nsContentUtils.h" | ||
#include "nsHTTPSOnlyUtils.h" | ||
#include "nsIConsoleService.h" | ||
#include "nsIScriptError.h" | ||
|
||
/* static */ | ||
bool nsHTTPSOnlyUtils::ShouldUpgradeRequest(nsIURI* aURI, | ||
nsILoadInfo* aLoadInfo) { | ||
// 1. Check if HTTPS-Only mode is enabled | ||
if (!mozilla::StaticPrefs::dom_security_https_only_mode()) { | ||
return false; | ||
} | ||
// 2. Check if NoUpgrade-flag is set in LoadInfo | ||
if (aLoadInfo->GetHttpsOnlyNoUpgrade()) { | ||
// Let's log to the console, that we didn't upgrade this request | ||
uint32_t innerWindowId = aLoadInfo->GetInnerWindowID(); | ||
AutoTArray<nsString, 2> params = { | ||
NS_ConvertUTF8toUTF16(aURI->GetSpecOrDefault())}; | ||
nsHTTPSOnlyUtils::LogLocalizedString( | ||
"HTTPSOnlyNoUpgrade", params, nsIScriptError::infoFlag, innerWindowId, | ||
!!aLoadInfo->GetOriginAttributes().mPrivateBrowsingId, aURI); | ||
return false; | ||
} | ||
|
||
// 3. Upgrade the request | ||
|
||
// Let's log it to the console | ||
// Append the additional 's' just for the logging | ||
nsAutoCString scheme; | ||
aURI->GetScheme(scheme); | ||
scheme.AppendLiteral("s"); | ||
NS_ConvertUTF8toUTF16 reportSpec(aURI->GetSpecOrDefault()); | ||
NS_ConvertUTF8toUTF16 reportScheme(scheme); | ||
|
||
uint32_t innerWindowId = aLoadInfo->GetInnerWindowID(); | ||
AutoTArray<nsString, 2> params = {reportSpec, reportScheme}; | ||
nsHTTPSOnlyUtils::LogLocalizedString( | ||
"HTTPSOnlyUpgradeRequest", params, nsIScriptError::warningFlag, | ||
innerWindowId, !!aLoadInfo->GetOriginAttributes().mPrivateBrowsingId, | ||
aURI); | ||
|
||
return true; | ||
} | ||
|
||
/** Logging **/ | ||
|
||
/* static */ | ||
void nsHTTPSOnlyUtils::LogLocalizedString( | ||
const char* aName, const nsTArray<nsString>& aParams, uint32_t aFlags, | ||
uint64_t aInnerWindowID, bool aFromPrivateWindow, nsIURI* aURI) { | ||
nsAutoString logMsg; | ||
nsContentUtils::FormatLocalizedString(nsContentUtils::eSECURITY_PROPERTIES, | ||
aName, aParams, logMsg); | ||
LogMessage(logMsg, aFlags, aInnerWindowID, aFromPrivateWindow, aURI); | ||
} | ||
|
||
/* static */ | ||
void nsHTTPSOnlyUtils::LogMessage(const nsAString& aMessage, uint32_t aFlags, | ||
uint64_t aInnerWindowID, | ||
bool aFromPrivateWindow, nsIURI* aURI) { | ||
// Prepending HTTPS-Only to the outgoing console message | ||
nsString message; | ||
message.AppendLiteral(u"HTTPS-Only Mode: "); | ||
message.Append(aMessage); | ||
|
||
// Allow for easy distinction in devtools code. | ||
nsCString category("HTTPSOnly"); | ||
|
||
if (aInnerWindowID > 0) { | ||
// Send to content console | ||
nsContentUtils::ReportToConsoleByWindowID(message, aFlags, category, | ||
aInnerWindowID, aURI); | ||
} else { | ||
// Send to browser console | ||
LogSimpleConsoleError(message, category.get(), aFromPrivateWindow, | ||
true /* from chrome context */, aFlags); | ||
} | ||
} | ||
|
||
/* static */ | ||
void nsHTTPSOnlyUtils::LogSimpleConsoleError(const nsAString& aErrorText, | ||
const char* aCategory, | ||
bool aFromPrivateWindow, | ||
bool aFromChromeContext, | ||
uint32_t aErrorFlags) { | ||
nsCOMPtr<nsIScriptError> scriptError = | ||
do_CreateInstance(NS_SCRIPTERROR_CONTRACTID); | ||
if (!scriptError) { | ||
return; | ||
} | ||
nsCOMPtr<nsIConsoleService> console = | ||
do_GetService(NS_CONSOLESERVICE_CONTRACTID); | ||
if (!console) { | ||
return; | ||
} | ||
nsresult rv = scriptError->Init(aErrorText, EmptyString(), EmptyString(), 0, | ||
0, aErrorFlags, aCategory, aFromPrivateWindow, | ||
aFromChromeContext); | ||
if (NS_FAILED(rv)) { | ||
return; | ||
} | ||
console->LogMessage(scriptError); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
/* -*- 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/. */ | ||
|
||
#ifndef nsHTTPSOnlyUtils_h___ | ||
#define nsHTTPSOnlyUtils_h___ | ||
|
||
#include "nsIScriptError.h" | ||
|
||
class nsHTTPSOnlyUtils { | ||
public: | ||
/** | ||
* Determines if a request should get because of the HTTPS-Only mode | ||
* @param aURI nsIURI of request | ||
* @param aLoadInfo nsILoadInfo of request | ||
* @param aShouldUpgrade true if request should get upgraded | ||
*/ | ||
static bool ShouldUpgradeRequest(nsIURI* aURI, nsILoadInfo* aLoadInfo); | ||
|
||
/** | ||
* Logs localized message to either content console or browser console | ||
* @param aName Localization key | ||
* @param aParams Localization parameters | ||
* @param aFlags Logging Flag (see nsIScriptError) | ||
* @param aInnerWindowID Inner Window ID (Logged on browser console if 0) | ||
* @param aFromPrivateWindow If from private window | ||
* @param [aURI] Optional: URI to log | ||
*/ | ||
static void LogLocalizedString(const char* aName, | ||
const nsTArray<nsString>& aParams, | ||
uint32_t aFlags, uint64_t aInnerWindowID, | ||
bool aFromPrivateWindow, | ||
nsIURI* aURI = nullptr); | ||
|
||
private: | ||
/** | ||
* Logs localized message to either content console or browser console | ||
* @param aMessage Message to log | ||
* @param aFlags Logging Flag (see nsIScriptError) | ||
* @param aInnerWindowID Inner Window ID (Logged on browser console if 0) | ||
* @param aFromPrivateWindow If from private window | ||
* @param [aURI] Optional: URI to log | ||
*/ | ||
static void LogMessage(const nsAString& aMessage, uint32_t aFlags, | ||
uint64_t aInnerWindowID, bool aFromPrivateWindow, | ||
nsIURI* aURI = nullptr); | ||
|
||
/** | ||
* Report simple error message to the browser console | ||
* @param aErrorText the error message | ||
* @param aCategory Name of the module reporting error | ||
* @param aFromPrivateWindow Whether from private window or not | ||
* @param aFromChromeContext Whether from chrome context or not | ||
* @param [aErrorFlags] See nsIScriptError. | ||
*/ | ||
static void LogSimpleConsoleError( | ||
const nsAString& aErrorText, const char* aCategory, | ||
bool aFromPrivateWindow, bool aFromChromeContext, | ||
uint32_t aErrorFlags = nsIScriptError::errorFlag); | ||
}; | ||
|
||
#endif /* nsHTTPSOnlyUtils_h___ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1613063 | ||
|
||
// Step 1. Send request with redirect queryString (eg. file_redirect.sjs?302) | ||
// Step 2. Server responds with corresponding redirect code to http://example.com/../file_redirect.sjs?check | ||
// Step 3. Response from ?check indicates whether the redirected request was secure or not. | ||
|
||
const RESPONSE_SECURE = "secure-ok"; | ||
const RESPONSE_INSECURE = "secure-error"; | ||
const RESPONSE_ERROR = "unexpected-query"; | ||
|
||
function handleRequest(request, response) { | ||
response.setHeader("Cache-Control", "no-cache", false); | ||
|
||
const query = request.queryString; | ||
|
||
// Send redirect header | ||
if ((query >= 301 && query <= 303) || query == 307) { | ||
const loc = | ||
"http://example.com/tests/dom/security/test/https-only/file_redirect.sjs?check"; | ||
response.setStatusLine(request.httpVersion, query, "Moved"); | ||
response.setHeader("Location", loc, false); | ||
return; | ||
} | ||
|
||
// Check if scheme is http:// oder https:// | ||
if (query == "check") { | ||
const secure = | ||
request.scheme == "https" ? RESPONSE_SECURE : RESPONSE_INSECURE; | ||
response.setStatusLine(request.httpVersion, 200, "OK"); | ||
response.write(secure); | ||
return; | ||
} | ||
|
||
// This should not happen | ||
response.setStatusLine(request.httpVersion, 500, "OK"); | ||
response.write(RESPONSE_ERROR); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
<!DOCTYPE HTML> | ||
<html> | ||
<head> | ||
<meta charset="utf-8"> | ||
<title>Bug 1613063 - HTTPS Only Mode</title> | ||
<!-- style --> | ||
<link rel='stylesheet' type='text/css' href='http://example.com/tests/dom/security/test/https-only/file_upgrade_insecure_server.sjs?style' media='screen' /> | ||
|
||
<!-- font --> | ||
<style> | ||
@font-face { | ||
font-family: "foofont"; | ||
src: url('http://example.com/tests/dom/security/test/https-only/file_upgrade_insecure_server.sjs?font'); | ||
} | ||
.div_foo { font-family: "foofont"; } | ||
</style> | ||
</head> | ||
<body> | ||
|
||
<!-- images: --> | ||
<img src="http://example.com/tests/dom/security/test/https-only/file_upgrade_insecure_server.sjs?img"></img> | ||
|
||
<!-- redirects: upgrade http:// to https:// redirect to http:// and then upgrade to https:// again --> | ||
<img src="http://example.com/tests/dom/security/test/https-only/file_upgrade_insecure_server.sjs?redirect-image"></img> | ||
|
||
<!-- script: --> | ||
<script src="http://example.com/tests/dom/security/test/https-only/file_upgrade_insecure_server.sjs?script"></script> | ||
|
||
<!-- media: --> | ||
<audio src="http://example.com/tests/dom/security/test/https-only/file_upgrade_insecure_server.sjs?media"></audio> | ||
|
||
<!-- objects: --> | ||
<object width="10" height="10" data="http://example.com/tests/dom/security/test/https-only/file_upgrade_insecure_server.sjs?object"></object> | ||
|
||
<!-- font: (apply font loaded in header to div) --> | ||
<div class="div_foo">foo</div> | ||
|
||
<!-- iframe: (same origin) --> | ||
<iframe src="http://example.com/tests/dom/security/test/https-only/file_upgrade_insecure_server.sjs?iframe"> | ||
<!-- within that iframe we load an image over http and make sure the requested gets upgraded to https --> | ||
</iframe> | ||
|
||
<!-- xhr: --> | ||
<script type="application/javascript"> | ||
var myXHR = new XMLHttpRequest(); | ||
myXHR.open("GET", "http://example.com/tests/dom/security/test/https-only/file_upgrade_insecure_server.sjs?xhr"); | ||
myXHR.send(null); | ||
</script> | ||
|
||
<!-- websockets: upgrade ws:// to wss://--> | ||
<script type="application/javascript"> | ||
// WebSocket tests are not supported on Android yet. Bug 1566168 | ||
const {AppConstants} = SpecialPowers.Cu.import("resource://gre/modules/AppConstants.jsm", {}); | ||
if (AppConstants.platform !== "android") { | ||
var mySocket = new WebSocket("ws://example.com/tests/dom/security/test/https-only/file_upgrade_insecure"); | ||
mySocket.onopen = function(e) { | ||
if (mySocket.url.includes("wss://")) { | ||
window.parent.postMessage({result: "websocket-ok"}, "*"); | ||
} | ||
else { | ||
window.parent.postMessage({result: "websocket-error"}, "*"); | ||
} | ||
mySocket.close(); | ||
}; | ||
mySocket.onerror = function(e) { | ||
// debug information for Bug 1316305 | ||
dump(" xxx mySocket.onerror: (mySocket): " + mySocket + "\n"); | ||
dump(" xxx mySocket.onerror: (mySocket.url): " + mySocket.url + "\n"); | ||
dump(" xxx mySocket.onerror: (e): " + e + "\n"); | ||
dump(" xxx mySocket.onerror: (e.message): " + e.message + "\n"); | ||
dump(" xxx mySocket.onerror: This might be related to Bug 1316305!\n"); | ||
window.parent.postMessage({result: "websocket-unexpected-error"}, "*"); | ||
}; | ||
} | ||
</script> | ||
|
||
<!-- form action: (upgrade POST from http:// to https://) --> | ||
<iframe name='formFrame' id='formFrame'></iframe> | ||
<form target="formFrame" action="http://example.com/tests/dom/security/test/https-only/file_upgrade_insecure_server.sjs?form" method="POST"> | ||
<input name="foo" value="foo"> | ||
<input type="submit" id="submitButton" formenctype='multipart/form-data' value="Submit form"> | ||
</form> | ||
<script type="text/javascript"> | ||
var submitButton = document.getElementById('submitButton'); | ||
submitButton.click(); | ||
</script> | ||
|
||
</body> | ||
</html> |
Oops, something went wrong.