mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-05 23:07:31 +09:00
Issue #2402 - CSP Violation events should have the correct sample for inline contexts. https://bugzilla.mozilla.org/show_bug.cgi?id=1473587 Add preference to increase max length of CSP report source sample. https://bugzilla.mozilla.org/show_bug.cgi?id=1415352 Return valid columnNumber value in CSP violation events. https://bugzilla.mozilla.org/show_bug.cgi?id=1418246
This commit is contained in:
parent
e74612e23e
commit
5b068f3726
38 changed files with 277 additions and 106 deletions
|
|
@ -535,7 +535,8 @@ NS_IMPL_ISUPPORTS(nsScriptSecurityManager,
|
||||||
///////////////// Security Checks /////////////////
|
///////////////// Security Checks /////////////////
|
||||||
|
|
||||||
bool
|
bool
|
||||||
nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(JSContext *cx)
|
nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(JSContext *cx,
|
||||||
|
JS::HandleValue aValue)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(cx == nsContentUtils::GetCurrentJSContext());
|
MOZ_ASSERT(cx == nsContentUtils::GetCurrentJSContext());
|
||||||
nsCOMPtr<nsIPrincipal> subjectPrincipal = nsContentUtils::SubjectPrincipal();
|
nsCOMPtr<nsIPrincipal> subjectPrincipal = nsContentUtils::SubjectPrincipal();
|
||||||
|
|
@ -558,12 +559,23 @@ nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(JSContext *cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reportViolation) {
|
if (reportViolation) {
|
||||||
nsAutoString fileName;
|
JS::Rooted<JSString*> jsString(cx, JS::ToString(cx, aValue));
|
||||||
unsigned lineNum = 0;
|
if (NS_WARN_IF(!jsString)) {
|
||||||
NS_NAMED_LITERAL_STRING(scriptSample, "call to eval() or related function blocked by CSP");
|
JS_ClearPendingException(cx);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsAutoJSString scriptSample;
|
||||||
|
if (NS_WARN_IF(!scriptSample.init(cx, jsString))) {
|
||||||
|
JS_ClearPendingException(cx);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
JS::AutoFilename scriptFilename;
|
JS::AutoFilename scriptFilename;
|
||||||
if (JS::DescribeScriptedCaller(cx, &scriptFilename, &lineNum)) {
|
nsAutoString fileName;
|
||||||
|
unsigned lineNum = 0;
|
||||||
|
unsigned columnNum = 0;
|
||||||
|
if (JS::DescribeScriptedCaller(cx, &scriptFilename, &lineNum, &columnNum)) {
|
||||||
if (const char *file = scriptFilename.get()) {
|
if (const char *file = scriptFilename.get()) {
|
||||||
CopyUTF8toUTF16(nsDependentCString(file), fileName);
|
CopyUTF8toUTF16(nsDependentCString(file), fileName);
|
||||||
}
|
}
|
||||||
|
|
@ -574,6 +586,7 @@ nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(JSContext *cx)
|
||||||
fileName,
|
fileName,
|
||||||
scriptSample,
|
scriptSample,
|
||||||
lineNum,
|
lineNum,
|
||||||
|
columnNum,
|
||||||
EmptyString(),
|
EmptyString(),
|
||||||
EmptyString());
|
EmptyString());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ private:
|
||||||
|
|
||||||
// Decides, based on CSP, whether or not eval() and stuff can be executed.
|
// Decides, based on CSP, whether or not eval() and stuff can be executed.
|
||||||
static bool
|
static bool
|
||||||
ContentSecurityPolicyPermitsJSAction(JSContext *cx);
|
ContentSecurityPolicyPermitsJSAction(JSContext *cx, JS::HandleValue aValue);
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
JSPrincipalsSubsume(JSPrincipals *first, JSPrincipals *second);
|
JSPrincipalsSubsume(JSPrincipals *first, JSPrincipals *second);
|
||||||
|
|
|
||||||
|
|
@ -11910,6 +11910,7 @@ nsIDocument::InlineScriptAllowedByCSP()
|
||||||
true, // aParserCreated
|
true, // aParserCreated
|
||||||
EmptyString(), // FIXME get script sample (bug 1314567)
|
EmptyString(), // FIXME get script sample (bug 1314567)
|
||||||
0, // aLineNumber
|
0, // aLineNumber
|
||||||
|
0, // aColumnNumber
|
||||||
&allowsInlineScript);
|
&allowsInlineScript);
|
||||||
NS_ENSURE_SUCCESS(rv, true);
|
NS_ENSURE_SUCCESS(rv, true);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,19 @@ public:
|
||||||
* was set
|
* was set
|
||||||
*/
|
*/
|
||||||
virtual uint32_t GetLineNumber() = 0;
|
virtual uint32_t GetLineNumber() = 0;
|
||||||
|
|
||||||
|
// This doesn't entirely belong here since they only make sense for
|
||||||
|
// some types of linking elements, but it's a better place than
|
||||||
|
// anywhere else.
|
||||||
|
virtual void SetColumnNumber(uint32_t aColumnNumber) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the column number, as previously set by SetColumnNumber.
|
||||||
|
*
|
||||||
|
* @return the column number of this element; or 1 if no column number
|
||||||
|
* was set
|
||||||
|
*/
|
||||||
|
virtual uint32_t GetColumnNumber() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIStyleSheetLinkingElement,
|
NS_DEFINE_STATIC_IID_ACCESSOR(nsIStyleSheetLinkingElement,
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ nsStyleLinkElement::nsStyleLinkElement()
|
||||||
: mDontLoadStyle(false)
|
: mDontLoadStyle(false)
|
||||||
, mUpdatesEnabled(true)
|
, mUpdatesEnabled(true)
|
||||||
, mLineNumber(1)
|
, mLineNumber(1)
|
||||||
|
, mColumnNumber(1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -127,6 +128,18 @@ nsStyleLinkElement::GetLineNumber()
|
||||||
return mLineNumber;
|
return mLineNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* virtual */ void
|
||||||
|
nsStyleLinkElement::SetColumnNumber(uint32_t aColumnNumber)
|
||||||
|
{
|
||||||
|
mColumnNumber = aColumnNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* virtual */ uint32_t
|
||||||
|
nsStyleLinkElement::GetColumnNumber()
|
||||||
|
{
|
||||||
|
return mColumnNumber;
|
||||||
|
}
|
||||||
|
|
||||||
/* static */ bool
|
/* static */ bool
|
||||||
nsStyleLinkElement::IsImportEnabled()
|
nsStyleLinkElement::IsImportEnabled()
|
||||||
{
|
{
|
||||||
|
|
@ -412,8 +425,10 @@ nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
|
||||||
if (!nsStyleUtil::CSPAllowsInlineStyle(thisContent,
|
if (!nsStyleUtil::CSPAllowsInlineStyle(thisContent,
|
||||||
thisContent->NodePrincipal(),
|
thisContent->NodePrincipal(),
|
||||||
doc->GetDocumentURI(),
|
doc->GetDocumentURI(),
|
||||||
mLineNumber, text, &rv))
|
mLineNumber, mColumnNumber, text,
|
||||||
|
&rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
// Parse the style sheet.
|
// Parse the style sheet.
|
||||||
rv = doc->CSSLoader()->
|
rv = doc->CSSLoader()->
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,8 @@ public:
|
||||||
virtual void OverrideBaseURI(nsIURI* aNewBaseURI) override;
|
virtual void OverrideBaseURI(nsIURI* aNewBaseURI) override;
|
||||||
virtual void SetLineNumber(uint32_t aLineNumber) override;
|
virtual void SetLineNumber(uint32_t aLineNumber) override;
|
||||||
virtual uint32_t GetLineNumber() override;
|
virtual uint32_t GetLineNumber() override;
|
||||||
|
void SetColumnNumber(uint32_t aColumnNumber) override;
|
||||||
|
uint32_t GetColumnNumber() override;
|
||||||
|
|
||||||
enum RelValue {
|
enum RelValue {
|
||||||
ePREFETCH = 0x00000001,
|
ePREFETCH = 0x00000001,
|
||||||
|
|
@ -140,6 +142,7 @@ protected:
|
||||||
bool mDontLoadStyle;
|
bool mDontLoadStyle;
|
||||||
bool mUpdatesEnabled;
|
bool mUpdatesEnabled;
|
||||||
uint32_t mLineNumber;
|
uint32_t mLineNumber;
|
||||||
|
uint32_t mColumnNumber;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* nsStyleLinkElement_h___ */
|
#endif /* nsStyleLinkElement_h___ */
|
||||||
|
|
|
||||||
|
|
@ -191,7 +191,7 @@ nsStyledElement::ParseStyleAttribute(const nsAString& aValue,
|
||||||
|
|
||||||
if (!isNativeAnon &&
|
if (!isNativeAnon &&
|
||||||
!nsStyleUtil::CSPAllowsInlineStyle(nullptr, NodePrincipal(),
|
!nsStyleUtil::CSPAllowsInlineStyle(nullptr, NodePrincipal(),
|
||||||
doc->GetDocumentURI(), 0, aValue,
|
doc->GetDocumentURI(), 0, 0, aValue,
|
||||||
nullptr))
|
nullptr))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -786,28 +786,22 @@ EventListenerManager::SetEventHandler(nsIAtom* aName,
|
||||||
rv = doc->NodePrincipal()->GetCsp(getter_AddRefs(csp));
|
rv = doc->NodePrincipal()->GetCsp(getter_AddRefs(csp));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
if (csp) {
|
unsigned lineNum = 0;
|
||||||
// let's generate a script sample and pass it as aContent,
|
unsigned columnNum = 0;
|
||||||
// it will not match the hash, but allows us to pass
|
|
||||||
// the script sample in aContent.
|
|
||||||
nsAutoString scriptSample, attr, tagName(NS_LITERAL_STRING("UNKNOWN"));
|
|
||||||
aName->ToString(attr);
|
|
||||||
nsCOMPtr<nsIDOMNode> domNode(do_QueryInterface(mTarget));
|
|
||||||
if (domNode) {
|
|
||||||
domNode->GetNodeName(tagName);
|
|
||||||
}
|
|
||||||
// build a "script sample" based on what we know about this element
|
|
||||||
scriptSample.Assign(attr);
|
|
||||||
scriptSample.AppendLiteral(" attribute on ");
|
|
||||||
scriptSample.Append(tagName);
|
|
||||||
scriptSample.AppendLiteral(" element");
|
|
||||||
|
|
||||||
|
JSContext* cx = nsContentUtils::GetCurrentJSContext();
|
||||||
|
if (cx && !JS::DescribeScriptedCaller(cx, nullptr, &lineNum, &columnNum)) {
|
||||||
|
JS_ClearPendingException(cx);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (csp) {
|
||||||
bool allowsInlineScript = true;
|
bool allowsInlineScript = true;
|
||||||
rv = csp->GetAllowsInline(nsIContentPolicy::TYPE_SCRIPT,
|
rv = csp->GetAllowsInline(nsIContentPolicy::TYPE_SCRIPT,
|
||||||
EmptyString(), // aNonce
|
EmptyString(), // aNonce
|
||||||
true, // aParserCreated (true because attribute event handler)
|
true, // aParserCreated (true because attribute event handler)
|
||||||
scriptSample,
|
aBody,
|
||||||
0, // aLineNumber
|
lineNum, // aLineNumber
|
||||||
|
columnNum, // aColumnNumber
|
||||||
&allowsInlineScript);
|
&allowsInlineScript);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -140,6 +140,8 @@ interface nsIContentSecurityPolicy : nsISerializable
|
||||||
* (and compare to the hashes listed in the policy)
|
* (and compare to the hashes listed in the policy)
|
||||||
* @param aLineNumber The line number of the inline resource
|
* @param aLineNumber The line number of the inline resource
|
||||||
* (used for reporting)
|
* (used for reporting)
|
||||||
|
* @param aColumnNumber The column number of the inline resource
|
||||||
|
* (used for reporting)
|
||||||
* @return
|
* @return
|
||||||
* Whether or not the effects of the inline style should be allowed
|
* Whether or not the effects of the inline style should be allowed
|
||||||
* (block the rules if false).
|
* (block the rules if false).
|
||||||
|
|
@ -148,7 +150,8 @@ interface nsIContentSecurityPolicy : nsISerializable
|
||||||
in AString aNonce,
|
in AString aNonce,
|
||||||
in boolean aParserCreated,
|
in boolean aParserCreated,
|
||||||
in AString aContent,
|
in AString aContent,
|
||||||
in unsigned long aLineNumber);
|
in unsigned long aLineNumber,
|
||||||
|
in unsigned long aColumnNumber);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* whether this policy allows eval and eval-like functions
|
* whether this policy allows eval and eval-like functions
|
||||||
|
|
@ -188,6 +191,8 @@ interface nsIContentSecurityPolicy : nsISerializable
|
||||||
* sample of the violating content (to aid debugging)
|
* sample of the violating content (to aid debugging)
|
||||||
* @param lineNum
|
* @param lineNum
|
||||||
* source line number of the violation (if available)
|
* source line number of the violation (if available)
|
||||||
|
* @param columnNum
|
||||||
|
* source column number of the violation (if available)
|
||||||
* @param aNonce
|
* @param aNonce
|
||||||
* (optional) If this is a nonce violation, include the nonce so we can
|
* (optional) If this is a nonce violation, include the nonce so we can
|
||||||
* recheck to determine which policies were violated and send the
|
* recheck to determine which policies were violated and send the
|
||||||
|
|
@ -202,6 +207,7 @@ interface nsIContentSecurityPolicy : nsISerializable
|
||||||
in AString sourceFile,
|
in AString sourceFile,
|
||||||
in AString scriptSample,
|
in AString scriptSample,
|
||||||
in int32_t lineNum,
|
in int32_t lineNum,
|
||||||
|
in int32_t columnNum,
|
||||||
[optional] in AString nonce,
|
[optional] in AString nonce,
|
||||||
[optional] in AString content);
|
[optional] in AString content);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -185,6 +185,7 @@ nsresult nsJSThunk::EvaluateScript(nsIChannel *aChannel,
|
||||||
true, // aParserCreated
|
true, // aParserCreated
|
||||||
EmptyString(), // aContent
|
EmptyString(), // aContent
|
||||||
0, // aLineNumber
|
0, // aLineNumber
|
||||||
|
0, // aColumnNumber
|
||||||
&allowsInlineScript);
|
&allowsInlineScript);
|
||||||
|
|
||||||
//return early if inline scripts are not allowed
|
//return early if inline scripts are not allowed
|
||||||
|
|
|
||||||
|
|
@ -1474,6 +1474,7 @@ CSPAllowsInlineScript(nsIScriptElement *aElement, nsIDocument *aDocument)
|
||||||
rv = csp->GetAllowsInline(nsIContentPolicy::TYPE_SCRIPT,
|
rv = csp->GetAllowsInline(nsIContentPolicy::TYPE_SCRIPT,
|
||||||
nonce, parserCreated, scriptText,
|
nonce, parserCreated, scriptText,
|
||||||
aElement->GetScriptLineNumber(),
|
aElement->GetScriptLineNumber(),
|
||||||
|
aElement->GetScriptColumnNumber(),
|
||||||
&allowInlineScript);
|
&allowInlineScript);
|
||||||
return allowInlineScript;
|
return allowInlineScript;
|
||||||
}
|
}
|
||||||
|
|
@ -2695,10 +2696,11 @@ ScriptLoader::VerifySRI(ScriptLoadRequest* aRequest,
|
||||||
nsAutoCString violationURISpec;
|
nsAutoCString violationURISpec;
|
||||||
mDocument->GetDocumentURI()->GetAsciiSpec(violationURISpec);
|
mDocument->GetDocumentURI()->GetAsciiSpec(violationURISpec);
|
||||||
uint32_t lineNo = aRequest->Element() ? aRequest->Element()->GetScriptLineNumber() : 0;
|
uint32_t lineNo = aRequest->Element() ? aRequest->Element()->GetScriptLineNumber() : 0;
|
||||||
|
uint32_t columnNo = aRequest->Element() ? aRequest->Element()->GetScriptColumnNumber() : 0;
|
||||||
csp->LogViolationDetails(
|
csp->LogViolationDetails(
|
||||||
nsIContentSecurityPolicy::VIOLATION_TYPE_REQUIRE_SRI_FOR_SCRIPT,
|
nsIContentSecurityPolicy::VIOLATION_TYPE_REQUIRE_SRI_FOR_SCRIPT,
|
||||||
NS_ConvertUTF8toUTF16(violationURISpec),
|
NS_ConvertUTF8toUTF16(violationURISpec),
|
||||||
EmptyString(), lineNo, EmptyString(), EmptyString());
|
EmptyString(), lineNo, columnNo, EmptyString(), EmptyString());
|
||||||
rv = NS_ERROR_SRI_CORRUPT;
|
rv = NS_ERROR_SRI_CORRUPT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ public:
|
||||||
|
|
||||||
explicit nsIScriptElement(mozilla::dom::FromParser aFromParser)
|
explicit nsIScriptElement(mozilla::dom::FromParser aFromParser)
|
||||||
: mLineNumber(1),
|
: mLineNumber(1),
|
||||||
|
mColumnNumber(1),
|
||||||
mAlreadyStarted(false),
|
mAlreadyStarted(false),
|
||||||
mMalformed(false),
|
mMalformed(false),
|
||||||
mDoneAddingChildren(aFromParser == mozilla::dom::NOT_FROM_PARSER ||
|
mDoneAddingChildren(aFromParser == mozilla::dom::NOT_FROM_PARSER ||
|
||||||
|
|
@ -138,6 +139,16 @@ public:
|
||||||
return mLineNumber;
|
return mLineNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetScriptColumnNumber(uint32_t aColumnNumber)
|
||||||
|
{
|
||||||
|
mColumnNumber = aColumnNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t GetScriptColumnNumber()
|
||||||
|
{
|
||||||
|
return mColumnNumber;
|
||||||
|
}
|
||||||
|
|
||||||
void SetIsMalformed()
|
void SetIsMalformed()
|
||||||
{
|
{
|
||||||
mMalformed = true;
|
mMalformed = true;
|
||||||
|
|
@ -281,6 +292,11 @@ protected:
|
||||||
*/
|
*/
|
||||||
uint32_t mLineNumber;
|
uint32_t mLineNumber;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The start column number of the script.
|
||||||
|
*/
|
||||||
|
uint32_t mColumnNumber;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The "already started" flag per HTML5.
|
* The "already started" flag per HTML5.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ CheckInternal(nsIContentSecurityPolicy* aCSP,
|
||||||
if (reportViolation) {
|
if (reportViolation) {
|
||||||
aCSP->LogViolationDetails(nsIContentSecurityPolicy::VIOLATION_TYPE_EVAL,
|
aCSP->LogViolationDetails(nsIContentSecurityPolicy::VIOLATION_TYPE_EVAL,
|
||||||
aFileNameString, aExpression, aLineNum,
|
aFileNameString, aExpression, aLineNum,
|
||||||
EmptyString(), EmptyString());
|
aColumnNum, EmptyString(), EmptyString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@
|
||||||
#include "nsScriptSecurityManager.h"
|
#include "nsScriptSecurityManager.h"
|
||||||
#include "nsStringStream.h"
|
#include "nsStringStream.h"
|
||||||
#include "mozilla/Logging.h"
|
#include "mozilla/Logging.h"
|
||||||
|
#include "mozilla/Preferences.h"
|
||||||
#include "mozilla/dom/CSPReportBinding.h"
|
#include "mozilla/dom/CSPReportBinding.h"
|
||||||
#include "mozilla/dom/CSPDictionariesBinding.h"
|
#include "mozilla/dom/CSPDictionariesBinding.h"
|
||||||
#include "mozilla/net/ReferrerPolicy.h"
|
#include "mozilla/net/ReferrerPolicy.h"
|
||||||
|
|
@ -271,7 +272,8 @@ nsCSPContext::permitsInternal(CSPDirective aDir,
|
||||||
EmptyString(), /* no observer subject */
|
EmptyString(), /* no observer subject */
|
||||||
EmptyString(), /* no source file */
|
EmptyString(), /* no source file */
|
||||||
EmptyString(), /* no script sample */
|
EmptyString(), /* no script sample */
|
||||||
0); /* no line number */
|
0, /* no line number */
|
||||||
|
0); /* no column number */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -298,6 +300,14 @@ nsCSPContext::nsCSPContext()
|
||||||
, mLoadingPrincipal(nullptr)
|
, mLoadingPrincipal(nullptr)
|
||||||
, mQueueUpMessages(true)
|
, mQueueUpMessages(true)
|
||||||
{
|
{
|
||||||
|
static bool sInitialized = false;
|
||||||
|
if (!sInitialized) {
|
||||||
|
Preferences::AddIntVarCache(&sScriptSampleMaxLength,
|
||||||
|
"security.csp.reporting.script-sample.max-length",
|
||||||
|
40);
|
||||||
|
sInitialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
CSPCONTEXTLOG(("nsCSPContext::nsCSPContext"));
|
CSPCONTEXTLOG(("nsCSPContext::nsCSPContext"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -470,7 +480,8 @@ nsCSPContext::reportInlineViolation(nsContentPolicyType aContentType,
|
||||||
const nsAString& aContent,
|
const nsAString& aContent,
|
||||||
const nsAString& aViolatedDirective,
|
const nsAString& aViolatedDirective,
|
||||||
uint32_t aViolatedPolicyIndex, // TODO, use report only flag for that
|
uint32_t aViolatedPolicyIndex, // TODO, use report only flag for that
|
||||||
uint32_t aLineNumber)
|
uint32_t aLineNumber,
|
||||||
|
uint32_t aColumnNumber)
|
||||||
{
|
{
|
||||||
nsString observerSubject;
|
nsString observerSubject;
|
||||||
// if the nonce is non empty, then we report the nonce error, otherwise
|
// if the nonce is non empty, then we report the nonce error, otherwise
|
||||||
|
|
@ -500,9 +511,9 @@ nsCSPContext::reportInlineViolation(nsContentPolicyType aContentType,
|
||||||
}
|
}
|
||||||
|
|
||||||
nsAutoString codeSample(aContent);
|
nsAutoString codeSample(aContent);
|
||||||
// cap the length of the script sample at 40 chars
|
// cap the length of the script sample
|
||||||
if (codeSample.Length() > 40) {
|
if (codeSample.Length() > ScriptSampleMaxLength()) {
|
||||||
codeSample.Truncate(40);
|
codeSample.Truncate(ScriptSampleMaxLength());
|
||||||
codeSample.AppendLiteral("...");
|
codeSample.AppendLiteral("...");
|
||||||
}
|
}
|
||||||
AsyncReportViolation(selfISupports, // aBlockedContentSource
|
AsyncReportViolation(selfISupports, // aBlockedContentSource
|
||||||
|
|
@ -512,7 +523,8 @@ nsCSPContext::reportInlineViolation(nsContentPolicyType aContentType,
|
||||||
observerSubject, // aObserverSubject
|
observerSubject, // aObserverSubject
|
||||||
NS_ConvertUTF8toUTF16(sourceFile), // aSourceFile
|
NS_ConvertUTF8toUTF16(sourceFile), // aSourceFile
|
||||||
codeSample, // aScriptSample
|
codeSample, // aScriptSample
|
||||||
aLineNumber); // aLineNum
|
aLineNumber, // aLineNum
|
||||||
|
aColumnNumber); // aColumnNum
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
|
@ -521,6 +533,7 @@ nsCSPContext::GetAllowsInline(nsContentPolicyType aContentType,
|
||||||
bool aParserCreated,
|
bool aParserCreated,
|
||||||
const nsAString& aContent,
|
const nsAString& aContent,
|
||||||
uint32_t aLineNumber,
|
uint32_t aLineNumber,
|
||||||
|
uint32_t aColumnNumber,
|
||||||
bool* outAllowsInline)
|
bool* outAllowsInline)
|
||||||
{
|
{
|
||||||
*outAllowsInline = true;
|
*outAllowsInline = true;
|
||||||
|
|
@ -565,7 +578,8 @@ nsCSPContext::GetAllowsInline(nsContentPolicyType aContentType,
|
||||||
aContent,
|
aContent,
|
||||||
violatedDirective,
|
violatedDirective,
|
||||||
i,
|
i,
|
||||||
aLineNumber);
|
aLineNumber,
|
||||||
|
aColumnNumber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
@ -584,7 +598,8 @@ nsCSPContext::GetAllowsInline(nsContentPolicyType aContentType,
|
||||||
* which is why we must check allows() again here.
|
* which is why we must check allows() again here.
|
||||||
*
|
*
|
||||||
* Note: This macro uses some parameters from its caller's context:
|
* Note: This macro uses some parameters from its caller's context:
|
||||||
* p, mPolicies, this, aSourceFile, aScriptSample, aLineNum, selfISupports
|
* p, mPolicies, this, aSourceFile, aScriptSample, aLineNum, aColumnNum,
|
||||||
|
* selfISupports
|
||||||
*
|
*
|
||||||
* @param violationType: the VIOLATION_TYPE_* constant (partial symbol)
|
* @param violationType: the VIOLATION_TYPE_* constant (partial symbol)
|
||||||
* such as INLINE_SCRIPT
|
* such as INLINE_SCRIPT
|
||||||
|
|
@ -611,8 +626,8 @@ nsCSPContext::GetAllowsInline(nsContentPolicyType aContentType,
|
||||||
nsIContentPolicy::TYPE_ ## contentPolicyType, \
|
nsIContentPolicy::TYPE_ ## contentPolicyType, \
|
||||||
violatedDirective); \
|
violatedDirective); \
|
||||||
this->AsyncReportViolation(selfISupports, nullptr, violatedDirective, p, \
|
this->AsyncReportViolation(selfISupports, nullptr, violatedDirective, p, \
|
||||||
NS_LITERAL_STRING(observerTopic), \
|
NS_LITERAL_STRING(observerTopic), aSourceFile,\
|
||||||
aSourceFile, aScriptSample, aLineNum); \
|
aScriptSample, aLineNum, aColumnNum); \
|
||||||
} \
|
} \
|
||||||
PR_END_MACRO; \
|
PR_END_MACRO; \
|
||||||
break
|
break
|
||||||
|
|
@ -644,6 +659,7 @@ nsCSPContext::LogViolationDetails(uint16_t aViolationType,
|
||||||
const nsAString& aSourceFile,
|
const nsAString& aSourceFile,
|
||||||
const nsAString& aScriptSample,
|
const nsAString& aScriptSample,
|
||||||
int32_t aLineNum,
|
int32_t aLineNum,
|
||||||
|
int32_t aColumnNum,
|
||||||
const nsAString& aNonce,
|
const nsAString& aNonce,
|
||||||
const nsAString& aContent)
|
const nsAString& aContent)
|
||||||
{
|
{
|
||||||
|
|
@ -844,6 +860,7 @@ nsCSPContext::GatherSecurityPolicyViolationEventData(
|
||||||
nsAString& aSourceFile,
|
nsAString& aSourceFile,
|
||||||
nsAString& aScriptSample,
|
nsAString& aScriptSample,
|
||||||
uint32_t aLineNum,
|
uint32_t aLineNum,
|
||||||
|
uint32_t aColumnNum,
|
||||||
mozilla::dom::SecurityPolicyViolationEventInit& aViolationEventInit)
|
mozilla::dom::SecurityPolicyViolationEventInit& aViolationEventInit)
|
||||||
{
|
{
|
||||||
NS_ENSURE_ARG_MAX(aViolatedPolicyIndex, mPolicies.Length() - 1);
|
NS_ENSURE_ARG_MAX(aViolatedPolicyIndex, mPolicies.Length() - 1);
|
||||||
|
|
@ -907,8 +924,19 @@ nsCSPContext::GatherSecurityPolicyViolationEventData(
|
||||||
aViolationEventInit.mSourceFile = aSourceFile;
|
aViolationEventInit.mSourceFile = aSourceFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
// sample
|
// sample, max 40 chars.
|
||||||
aViolationEventInit.mSample = aScriptSample;
|
aViolationEventInit.mSample = aScriptSample;
|
||||||
|
uint32_t length = aViolationEventInit.mSample.Length();
|
||||||
|
if (length > ScriptSampleMaxLength()) {
|
||||||
|
uint32_t desiredLength = ScriptSampleMaxLength();
|
||||||
|
// Don't cut off right before a low surrogate. Just include it.
|
||||||
|
if (NS_IS_LOW_SURROGATE(aViolationEventInit.mSample[desiredLength])) {
|
||||||
|
desiredLength++;
|
||||||
|
}
|
||||||
|
aViolationEventInit.mSample.Replace(ScriptSampleMaxLength(),
|
||||||
|
length - desiredLength,
|
||||||
|
nsContentUtils::GetLocalizedEllipsis());
|
||||||
|
}
|
||||||
|
|
||||||
// disposition
|
// disposition
|
||||||
aViolationEventInit.mDisposition = mPolicies[aViolatedPolicyIndex]->getReportOnlyFlag()
|
aViolationEventInit.mDisposition = mPolicies[aViolatedPolicyIndex]->getReportOnlyFlag()
|
||||||
|
|
@ -936,8 +964,7 @@ nsCSPContext::GatherSecurityPolicyViolationEventData(
|
||||||
aViolationEventInit.mLineNumber = aLineNum;
|
aViolationEventInit.mLineNumber = aLineNum;
|
||||||
|
|
||||||
// column-number
|
// column-number
|
||||||
// TODO: Set correct column number.
|
aViolationEventInit.mColumnNumber = aColumnNum;
|
||||||
aViolationEventInit.mColumnNumber = 0;
|
|
||||||
|
|
||||||
aViolationEventInit.mBubbles = true;
|
aViolationEventInit.mBubbles = true;
|
||||||
aViolationEventInit.mComposed = true;
|
aViolationEventInit.mComposed = true;
|
||||||
|
|
@ -1012,7 +1039,8 @@ nsCSPContext::SendReports(
|
||||||
reportURICstring.get()));
|
reportURICstring.get()));
|
||||||
logToConsole(u"triedToSendReport", params, ArrayLength(params),
|
logToConsole(u"triedToSendReport", params, ArrayLength(params),
|
||||||
aViolationEventInit.mSourceFile, aViolationEventInit.mSample,
|
aViolationEventInit.mSourceFile, aViolationEventInit.mSample,
|
||||||
aViolationEventInit.mLineNumber, 0, nsIScriptError::errorFlag);
|
aViolationEventInit.mLineNumber, aViolationEventInit.mColumnNumber,
|
||||||
|
nsIScriptError::errorFlag);
|
||||||
continue; // don't return yet, there may be more URIs
|
continue; // don't return yet, there may be more URIs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1054,7 +1082,8 @@ nsCSPContext::SendReports(
|
||||||
const char16_t* params[] = { reportURIs[r].get() };
|
const char16_t* params[] = { reportURIs[r].get() };
|
||||||
logToConsole(u"reportURInotHttpsOrHttp2", params, ArrayLength(params),
|
logToConsole(u"reportURInotHttpsOrHttp2", params, ArrayLength(params),
|
||||||
aViolationEventInit.mSourceFile, aViolationEventInit.mSample,
|
aViolationEventInit.mSourceFile, aViolationEventInit.mSample,
|
||||||
aViolationEventInit.mLineNumber, 0, nsIScriptError::errorFlag);
|
aViolationEventInit.mLineNumber, aViolationEventInit.mColumnNumber,
|
||||||
|
nsIScriptError::errorFlag);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1119,7 +1148,8 @@ nsCSPContext::SendReports(
|
||||||
CSPCONTEXTLOG(("AsyncOpen failed for report URI %s", params[0]));
|
CSPCONTEXTLOG(("AsyncOpen failed for report URI %s", params[0]));
|
||||||
logToConsole(u"triedToSendReport", params, ArrayLength(params),
|
logToConsole(u"triedToSendReport", params, ArrayLength(params),
|
||||||
aViolationEventInit.mSourceFile, aViolationEventInit.mSample,
|
aViolationEventInit.mSourceFile, aViolationEventInit.mSample,
|
||||||
aViolationEventInit.mLineNumber, 0, nsIScriptError::errorFlag);
|
aViolationEventInit.mLineNumber, aViolationEventInit.mColumnNumber,
|
||||||
|
nsIScriptError::errorFlag);
|
||||||
} else {
|
} else {
|
||||||
CSPCONTEXTLOG(("Sent violation report to URI %s", reportURICstring.get()));
|
CSPCONTEXTLOG(("Sent violation report to URI %s", reportURICstring.get()));
|
||||||
}
|
}
|
||||||
|
|
@ -1162,6 +1192,7 @@ class CSPReportSenderRunnable final : public Runnable
|
||||||
const nsAString& aSourceFile,
|
const nsAString& aSourceFile,
|
||||||
const nsAString& aScriptSample,
|
const nsAString& aScriptSample,
|
||||||
uint32_t aLineNum,
|
uint32_t aLineNum,
|
||||||
|
uint32_t aColumnNum,
|
||||||
nsCSPContext* aCSPContext)
|
nsCSPContext* aCSPContext)
|
||||||
: mBlockedContentSource(aBlockedContentSource)
|
: mBlockedContentSource(aBlockedContentSource)
|
||||||
, mOriginalURI(aOriginalURI)
|
, mOriginalURI(aOriginalURI)
|
||||||
|
|
@ -1171,6 +1202,7 @@ class CSPReportSenderRunnable final : public Runnable
|
||||||
, mSourceFile(aSourceFile)
|
, mSourceFile(aSourceFile)
|
||||||
, mScriptSample(aScriptSample)
|
, mScriptSample(aScriptSample)
|
||||||
, mLineNum(aLineNum)
|
, mLineNum(aLineNum)
|
||||||
|
, mColumnNum(aColumnNum)
|
||||||
, mCSPContext(aCSPContext)
|
, mCSPContext(aCSPContext)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(!aViolatedDirective.IsEmpty(), "Can not send reports without a violated directive");
|
NS_ASSERTION(!aViolatedDirective.IsEmpty(), "Can not send reports without a violated directive");
|
||||||
|
|
@ -1208,7 +1240,7 @@ class CSPReportSenderRunnable final : public Runnable
|
||||||
blockedURI, blockedDataStr, mOriginalURI,
|
blockedURI, blockedDataStr, mOriginalURI,
|
||||||
mViolatedDirective, mViolatedPolicyIndex,
|
mViolatedDirective, mViolatedPolicyIndex,
|
||||||
mSourceFile, mScriptSample, mLineNum,
|
mSourceFile, mScriptSample, mLineNum,
|
||||||
init);
|
mColumnNum, init);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
// 1) notify observers
|
// 1) notify observers
|
||||||
|
|
@ -1223,15 +1255,22 @@ class CSPReportSenderRunnable final : public Runnable
|
||||||
mCSPContext->SendReports(init, mViolatedPolicyIndex);
|
mCSPContext->SendReports(init, mViolatedPolicyIndex);
|
||||||
|
|
||||||
// 3) log to console (one per policy violation)
|
// 3) log to console (one per policy violation)
|
||||||
|
// if mBlockedContentSource is not a URI, it could be a string
|
||||||
|
nsCOMPtr<nsISupportsCString> blockedString = do_QueryInterface(mBlockedContentSource);
|
||||||
|
|
||||||
if (blockedURI) {
|
if (blockedURI) {
|
||||||
blockedURI->GetSpec(blockedDataStr);
|
blockedURI->GetSpec(blockedDataStr);
|
||||||
bool isData = false;
|
if (blockedDataStr.Length() > nsCSPContext::ScriptSampleMaxLength()) {
|
||||||
rv = blockedURI->SchemeIs("data", &isData);
|
bool isData = false;
|
||||||
if (NS_SUCCEEDED(rv) && isData) {
|
rv = blockedURI->SchemeIs("data", &isData);
|
||||||
blockedDataStr.Truncate(40);
|
if (NS_SUCCEEDED(rv) && isData &&
|
||||||
blockedDataStr.AppendASCII("...");
|
blockedDataStr.Length() > nsCSPContext::ScriptSampleMaxLength()) {
|
||||||
|
blockedDataStr.Truncate(nsCSPContext::ScriptSampleMaxLength());
|
||||||
|
blockedDataStr.Append(NS_ConvertUTF16toUTF8(nsContentUtils::GetLocalizedEllipsis()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else if (blockedString) {
|
||||||
|
blockedString->GetData(blockedDataStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blockedDataStr.Length() > 0) {
|
if (blockedDataStr.Length() > 0) {
|
||||||
|
|
@ -1241,7 +1280,7 @@ class CSPReportSenderRunnable final : public Runnable
|
||||||
mCSPContext->logToConsole(mReportOnlyFlag ? u"CSPROViolationWithURI" :
|
mCSPContext->logToConsole(mReportOnlyFlag ? u"CSPROViolationWithURI" :
|
||||||
u"CSPViolationWithURI",
|
u"CSPViolationWithURI",
|
||||||
params, ArrayLength(params), mSourceFile, mScriptSample,
|
params, ArrayLength(params), mSourceFile, mScriptSample,
|
||||||
mLineNum, 0, nsIScriptError::errorFlag);
|
mLineNum, mColumnNum, nsIScriptError::errorFlag);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4) fire violation event
|
// 4) fire violation event
|
||||||
|
|
@ -1260,6 +1299,7 @@ class CSPReportSenderRunnable final : public Runnable
|
||||||
nsString mSourceFile;
|
nsString mSourceFile;
|
||||||
nsString mScriptSample;
|
nsString mScriptSample;
|
||||||
uint32_t mLineNum;
|
uint32_t mLineNum;
|
||||||
|
uint32_t mColumnNum;
|
||||||
RefPtr<nsCSPContext> mCSPContext;
|
RefPtr<nsCSPContext> mCSPContext;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1287,6 +1327,8 @@ class CSPReportSenderRunnable final : public Runnable
|
||||||
* a sample of the violating inline script
|
* a sample of the violating inline script
|
||||||
* @param aLineNum
|
* @param aLineNum
|
||||||
* source line number of the violation (if available)
|
* source line number of the violation (if available)
|
||||||
|
* @param aColumnNum
|
||||||
|
* source column number of the violation (if available)
|
||||||
*/
|
*/
|
||||||
nsresult
|
nsresult
|
||||||
nsCSPContext::AsyncReportViolation(nsISupports* aBlockedContentSource,
|
nsCSPContext::AsyncReportViolation(nsISupports* aBlockedContentSource,
|
||||||
|
|
@ -1296,7 +1338,8 @@ nsCSPContext::AsyncReportViolation(nsISupports* aBlockedContentSource,
|
||||||
const nsAString& aObserverSubject,
|
const nsAString& aObserverSubject,
|
||||||
const nsAString& aSourceFile,
|
const nsAString& aSourceFile,
|
||||||
const nsAString& aScriptSample,
|
const nsAString& aScriptSample,
|
||||||
uint32_t aLineNum)
|
uint32_t aLineNum,
|
||||||
|
uint32_t aColumnNum)
|
||||||
{
|
{
|
||||||
NS_ENSURE_ARG_MAX(aViolatedPolicyIndex, mPolicies.Length() - 1);
|
NS_ENSURE_ARG_MAX(aViolatedPolicyIndex, mPolicies.Length() - 1);
|
||||||
|
|
||||||
|
|
@ -1309,6 +1352,7 @@ nsCSPContext::AsyncReportViolation(nsISupports* aBlockedContentSource,
|
||||||
aSourceFile,
|
aSourceFile,
|
||||||
aScriptSample,
|
aScriptSample,
|
||||||
aLineNum,
|
aLineNum,
|
||||||
|
aColumnNum,
|
||||||
this));
|
this));
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,7 @@ class nsCSPContext : public nsIContentSecurityPolicy
|
||||||
nsAString& aSourceFile,
|
nsAString& aSourceFile,
|
||||||
nsAString& aScriptSample,
|
nsAString& aScriptSample,
|
||||||
uint32_t aLineNum,
|
uint32_t aLineNum,
|
||||||
|
uint32_t aColumnNum,
|
||||||
mozilla::dom::SecurityPolicyViolationEventInit& aViolationEventInit);
|
mozilla::dom::SecurityPolicyViolationEventInit& aViolationEventInit);
|
||||||
|
|
||||||
nsresult SendReports(
|
nsresult SendReports(
|
||||||
|
|
@ -101,7 +102,8 @@ class nsCSPContext : public nsIContentSecurityPolicy
|
||||||
const nsAString& aObserverSubject,
|
const nsAString& aObserverSubject,
|
||||||
const nsAString& aSourceFile,
|
const nsAString& aSourceFile,
|
||||||
const nsAString& aScriptSample,
|
const nsAString& aScriptSample,
|
||||||
uint32_t aLineNum);
|
uint32_t aLineNum,
|
||||||
|
uint32_t aColumnNum);
|
||||||
|
|
||||||
// Hands off! Don't call this method unless you know what you
|
// Hands off! Don't call this method unless you know what you
|
||||||
// are doing. It's only supposed to be called from within
|
// are doing. It's only supposed to be called from within
|
||||||
|
|
@ -110,10 +112,14 @@ class nsCSPContext : public nsIContentSecurityPolicy
|
||||||
mLoadingPrincipal = nullptr;
|
mLoadingPrincipal = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsWeakPtr GetLoadingContext(){
|
nsWeakPtr GetLoadingContext() {
|
||||||
return mLoadingContext;
|
return mLoadingContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t ScriptSampleMaxLength() {
|
||||||
|
return std::max(sScriptSampleMaxLength, 0);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool permitsInternal(CSPDirective aDir,
|
bool permitsInternal(CSPDirective aDir,
|
||||||
nsIURI* aContentLocation,
|
nsIURI* aContentLocation,
|
||||||
|
|
@ -132,7 +138,10 @@ class nsCSPContext : public nsIContentSecurityPolicy
|
||||||
const nsAString& aContent,
|
const nsAString& aContent,
|
||||||
const nsAString& aViolatedDirective,
|
const nsAString& aViolatedDirective,
|
||||||
uint32_t aViolatedPolicyIndex,
|
uint32_t aViolatedPolicyIndex,
|
||||||
uint32_t aLineNumber);
|
uint32_t aLineNumber,
|
||||||
|
uint32_t aColumnNumber);
|
||||||
|
|
||||||
|
static int32_t sScriptSampleMaxLength;
|
||||||
|
|
||||||
nsString mReferrer;
|
nsString mReferrer;
|
||||||
uint64_t mInnerWindowID; // used for web console logging
|
uint64_t mInnerWindowID; // used for web console logging
|
||||||
|
|
|
||||||
|
|
@ -405,7 +405,7 @@ nsSMILCSSValueType::ValueFromString(nsCSSPropertyID aPropID,
|
||||||
if (doc && !nsStyleUtil::CSPAllowsInlineStyle(nullptr,
|
if (doc && !nsStyleUtil::CSPAllowsInlineStyle(nullptr,
|
||||||
doc->NodePrincipal(),
|
doc->NodePrincipal(),
|
||||||
doc->GetDocumentURI(),
|
doc->GetDocumentURI(),
|
||||||
0, aString, nullptr)) {
|
0, 0, aString, nullptr)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ dictionary CSPReportProperties {
|
||||||
DOMString source-file;
|
DOMString source-file;
|
||||||
DOMString script-sample;
|
DOMString script-sample;
|
||||||
long line-number;
|
long line-number;
|
||||||
|
long column-number;
|
||||||
};
|
};
|
||||||
|
|
||||||
dictionary CSPReport {
|
dictionary CSPReport {
|
||||||
|
|
|
||||||
|
|
@ -547,14 +547,21 @@ class LogViolationDetailsRunnable final : public WorkerMainThreadRunnable
|
||||||
{
|
{
|
||||||
nsString mFileName;
|
nsString mFileName;
|
||||||
uint32_t mLineNum;
|
uint32_t mLineNum;
|
||||||
|
uint32_t mColumnNum;
|
||||||
|
nsString mScriptSample;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LogViolationDetailsRunnable(WorkerPrivate* aWorker,
|
LogViolationDetailsRunnable(WorkerPrivate* aWorker,
|
||||||
const nsString& aFileName,
|
const nsString& aFileName,
|
||||||
uint32_t aLineNum)
|
uint32_t aLineNum,
|
||||||
|
uint32_t aColumnNum,
|
||||||
|
const nsAString& aScriptSample)
|
||||||
: WorkerMainThreadRunnable(aWorker,
|
: WorkerMainThreadRunnable(aWorker,
|
||||||
NS_LITERAL_CSTRING("RuntimeService :: LogViolationDetails"))
|
NS_LITERAL_CSTRING("RuntimeService :: LogViolationDetails"))
|
||||||
, mFileName(aFileName), mLineNum(aLineNum)
|
, mFileName(aFileName)
|
||||||
|
, mLineNum(aLineNum)
|
||||||
|
, mColumnNum(aColumnNum)
|
||||||
|
, mScriptSample(aScriptSample)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aWorker);
|
MOZ_ASSERT(aWorker);
|
||||||
}
|
}
|
||||||
|
|
@ -566,24 +573,38 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ContentSecurityPolicyAllows(JSContext* aCx)
|
ContentSecurityPolicyAllows(JSContext* aCx, JS::HandleValue aValue)
|
||||||
{
|
{
|
||||||
WorkerPrivate* worker = GetWorkerPrivateFromContext(aCx);
|
WorkerPrivate* worker = GetWorkerPrivateFromContext(aCx);
|
||||||
worker->AssertIsOnWorkerThread();
|
worker->AssertIsOnWorkerThread();
|
||||||
|
|
||||||
if (worker->GetReportCSPViolations()) {
|
if (worker->GetReportCSPViolations()) {
|
||||||
|
JS::Rooted<JSString*> jsString(aCx, JS::ToString(aCx, aValue));
|
||||||
|
if (NS_WARN_IF(!jsString)) {
|
||||||
|
JS_ClearPendingException(aCx);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsAutoJSString scriptSample;
|
||||||
|
if (NS_WARN_IF(!scriptSample.init(aCx, jsString))) {
|
||||||
|
JS_ClearPendingException(aCx);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
nsString fileName;
|
nsString fileName;
|
||||||
uint32_t lineNum = 0;
|
uint32_t lineNum = 0;
|
||||||
|
uint32_t columnNum = 0;
|
||||||
|
|
||||||
JS::AutoFilename file;
|
JS::AutoFilename file;
|
||||||
if (JS::DescribeScriptedCaller(aCx, &file, &lineNum) && file.get()) {
|
if (JS::DescribeScriptedCaller(aCx, &file, &lineNum, &columnNum) && file.get()) {
|
||||||
fileName = NS_ConvertUTF8toUTF16(file.get());
|
fileName = NS_ConvertUTF8toUTF16(file.get());
|
||||||
} else {
|
} else {
|
||||||
MOZ_ASSERT(!JS_IsExceptionPending(aCx));
|
MOZ_ASSERT(!JS_IsExceptionPending(aCx));
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<LogViolationDetailsRunnable> runnable =
|
RefPtr<LogViolationDetailsRunnable> runnable =
|
||||||
new LogViolationDetailsRunnable(worker, fileName, lineNum);
|
new LogViolationDetailsRunnable(worker, fileName, lineNum, columnNum,
|
||||||
|
scriptSample);
|
||||||
|
|
||||||
ErrorResult rv;
|
ErrorResult rv;
|
||||||
runnable->Dispatch(Killing, rv);
|
runnable->Dispatch(Killing, rv);
|
||||||
|
|
@ -2698,11 +2719,9 @@ LogViolationDetailsRunnable::MainThreadRun()
|
||||||
|
|
||||||
nsIContentSecurityPolicy* csp = mWorkerPrivate->GetCSP();
|
nsIContentSecurityPolicy* csp = mWorkerPrivate->GetCSP();
|
||||||
if (csp) {
|
if (csp) {
|
||||||
NS_NAMED_LITERAL_STRING(scriptSample,
|
|
||||||
"Call to eval() or related function blocked by CSP.");
|
|
||||||
if (mWorkerPrivate->GetReportCSPViolations()) {
|
if (mWorkerPrivate->GetReportCSPViolations()) {
|
||||||
csp->LogViolationDetails(nsIContentSecurityPolicy::VIOLATION_TYPE_EVAL,
|
csp->LogViolationDetails(nsIContentSecurityPolicy::VIOLATION_TYPE_EVAL,
|
||||||
mFileName, scriptSample, mLineNum,
|
mFileName, mScriptSample, mLineNum, mColumnNum,
|
||||||
EmptyString(), EmptyString());
|
EmptyString(), EmptyString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1167,7 +1167,7 @@ private:
|
||||||
if (wcsp) {
|
if (wcsp) {
|
||||||
wcsp->LogViolationDetails(
|
wcsp->LogViolationDetails(
|
||||||
nsIContentSecurityPolicy::VIOLATION_TYPE_REQUIRE_SRI_FOR_SCRIPT,
|
nsIContentSecurityPolicy::VIOLATION_TYPE_REQUIRE_SRI_FOR_SCRIPT,
|
||||||
aLoadInfo.mURL, EmptyString(), 0, EmptyString(), EmptyString());
|
aLoadInfo.mURL, EmptyString(), 0, 0, EmptyString(), EmptyString());
|
||||||
}
|
}
|
||||||
return NS_ERROR_SRI_CORRUPT;
|
return NS_ERROR_SRI_CORRUPT;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -248,10 +248,11 @@ NS_IMETHODIMP
|
||||||
nsXBLContentSink::HandleStartElement(const char16_t *aName,
|
nsXBLContentSink::HandleStartElement(const char16_t *aName,
|
||||||
const char16_t **aAtts,
|
const char16_t **aAtts,
|
||||||
uint32_t aAttsCount,
|
uint32_t aAttsCount,
|
||||||
uint32_t aLineNumber)
|
uint32_t aLineNumber,
|
||||||
|
uint32_t aColumnNumber)
|
||||||
{
|
{
|
||||||
nsresult rv = nsXMLContentSink::HandleStartElement(aName, aAtts, aAttsCount,
|
nsresult rv = nsXMLContentSink::HandleStartElement(aName, aAtts, aAttsCount,
|
||||||
aLineNumber);
|
aLineNumber, aColumnNumber);
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
|
|
@ -850,7 +851,8 @@ nsXBLContentSink::ConstructParameter(const char16_t **aAtts)
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsXBLContentSink::CreateElement(const char16_t** aAtts, uint32_t aAttsCount,
|
nsXBLContentSink::CreateElement(const char16_t** aAtts, uint32_t aAttsCount,
|
||||||
mozilla::dom::NodeInfo* aNodeInfo, uint32_t aLineNumber,
|
mozilla::dom::NodeInfo* aNodeInfo,
|
||||||
|
uint32_t aLineNumber, uint32_t aColumnNumber,
|
||||||
nsIContent** aResult, bool* aAppendContent,
|
nsIContent** aResult, bool* aAppendContent,
|
||||||
FromParser aFromParser)
|
FromParser aFromParser)
|
||||||
{
|
{
|
||||||
|
|
@ -858,7 +860,7 @@ nsXBLContentSink::CreateElement(const char16_t** aAtts, uint32_t aAttsCount,
|
||||||
if (!aNodeInfo->NamespaceEquals(kNameSpaceID_XUL)) {
|
if (!aNodeInfo->NamespaceEquals(kNameSpaceID_XUL)) {
|
||||||
#endif
|
#endif
|
||||||
return nsXMLContentSink::CreateElement(aAtts, aAttsCount, aNodeInfo,
|
return nsXMLContentSink::CreateElement(aAtts, aAttsCount, aNodeInfo,
|
||||||
aLineNumber, aResult,
|
aLineNumber, aColumnNumber, aResult,
|
||||||
aAppendContent, aFromParser);
|
aAppendContent, aFromParser);
|
||||||
#ifdef MOZ_XUL
|
#ifdef MOZ_XUL
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,8 @@ public:
|
||||||
NS_IMETHOD HandleStartElement(const char16_t *aName,
|
NS_IMETHOD HandleStartElement(const char16_t *aName,
|
||||||
const char16_t **aAtts,
|
const char16_t **aAtts,
|
||||||
uint32_t aAttsCount,
|
uint32_t aAttsCount,
|
||||||
uint32_t aLineNumber) override;
|
uint32_t aLineNumber,
|
||||||
|
uint32_t aColumnNumber) override;
|
||||||
|
|
||||||
NS_IMETHOD HandleEndElement(const char16_t *aName) override;
|
NS_IMETHOD HandleEndElement(const char16_t *aName) override;
|
||||||
|
|
||||||
|
|
@ -89,7 +90,8 @@ protected:
|
||||||
bool NotifyForDocElement() override { return false; }
|
bool NotifyForDocElement() override { return false; }
|
||||||
|
|
||||||
nsresult CreateElement(const char16_t** aAtts, uint32_t aAttsCount,
|
nsresult CreateElement(const char16_t** aAtts, uint32_t aAttsCount,
|
||||||
mozilla::dom::NodeInfo* aNodeInfo, uint32_t aLineNumber,
|
mozilla::dom::NodeInfo* aNodeInfo,
|
||||||
|
uint32_t aLineNumber, uint32_t aColumnNumber,
|
||||||
nsIContent** aResult, bool* aAppendContent,
|
nsIContent** aResult, bool* aAppendContent,
|
||||||
mozilla::dom::FromParser aFromParser) override;
|
mozilla::dom::FromParser aFromParser) override;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -446,7 +446,8 @@ nsXMLContentSink::SetParser(nsParserBase* aParser)
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsXMLContentSink::CreateElement(const char16_t** aAtts, uint32_t aAttsCount,
|
nsXMLContentSink::CreateElement(const char16_t** aAtts, uint32_t aAttsCount,
|
||||||
mozilla::dom::NodeInfo* aNodeInfo, uint32_t aLineNumber,
|
mozilla::dom::NodeInfo* aNodeInfo,
|
||||||
|
uint32_t aLineNumber, uint32_t aColumnNumber,
|
||||||
nsIContent** aResult, bool* aAppendContent,
|
nsIContent** aResult, bool* aAppendContent,
|
||||||
FromParser aFromParser)
|
FromParser aFromParser)
|
||||||
{
|
{
|
||||||
|
|
@ -466,6 +467,7 @@ nsXMLContentSink::CreateElement(const char16_t** aAtts, uint32_t aAttsCount,
|
||||||
) {
|
) {
|
||||||
nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(content);
|
nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(content);
|
||||||
sele->SetScriptLineNumber(aLineNumber);
|
sele->SetScriptLineNumber(aLineNumber);
|
||||||
|
sele->SetScriptColumnNumber(aColumnNumber);
|
||||||
sele->SetCreatorParser(GetParser());
|
sele->SetCreatorParser(GetParser());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -500,6 +502,7 @@ nsXMLContentSink::CreateElement(const char16_t** aAtts, uint32_t aAttsCount,
|
||||||
}
|
}
|
||||||
if (!aNodeInfo->Equals(nsGkAtoms::link, kNameSpaceID_XHTML)) {
|
if (!aNodeInfo->Equals(nsGkAtoms::link, kNameSpaceID_XHTML)) {
|
||||||
ssle->SetLineNumber(aFromParser ? aLineNumber : 0);
|
ssle->SetLineNumber(aFromParser ? aLineNumber : 0);
|
||||||
|
ssle->SetColumnNumber(aFromParser ? aColumnNumber : 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -918,10 +921,11 @@ NS_IMETHODIMP
|
||||||
nsXMLContentSink::HandleStartElement(const char16_t *aName,
|
nsXMLContentSink::HandleStartElement(const char16_t *aName,
|
||||||
const char16_t **aAtts,
|
const char16_t **aAtts,
|
||||||
uint32_t aAttsCount,
|
uint32_t aAttsCount,
|
||||||
uint32_t aLineNumber)
|
uint32_t aLineNumber,
|
||||||
|
uint32_t aColumnNumber)
|
||||||
{
|
{
|
||||||
return HandleStartElement(aName, aAtts, aAttsCount, aLineNumber,
|
return HandleStartElement(aName, aAtts, aAttsCount, aLineNumber,
|
||||||
true);
|
aColumnNumber, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
|
@ -929,6 +933,7 @@ nsXMLContentSink::HandleStartElement(const char16_t *aName,
|
||||||
const char16_t **aAtts,
|
const char16_t **aAtts,
|
||||||
uint32_t aAttsCount,
|
uint32_t aAttsCount,
|
||||||
uint32_t aLineNumber,
|
uint32_t aLineNumber,
|
||||||
|
uint32_t aColumnNumber,
|
||||||
bool aInterruptable)
|
bool aInterruptable)
|
||||||
{
|
{
|
||||||
NS_PRECONDITION(aAttsCount % 2 == 0, "incorrect aAttsCount");
|
NS_PRECONDITION(aAttsCount % 2 == 0, "incorrect aAttsCount");
|
||||||
|
|
@ -963,7 +968,7 @@ nsXMLContentSink::HandleStartElement(const char16_t *aName,
|
||||||
nsIDOMNode::ELEMENT_NODE);
|
nsIDOMNode::ELEMENT_NODE);
|
||||||
|
|
||||||
result = CreateElement(aAtts, aAttsCount, nodeInfo, aLineNumber,
|
result = CreateElement(aAtts, aAttsCount, nodeInfo, aLineNumber,
|
||||||
getter_AddRefs(content), &appendContent,
|
aColumnNumber, getter_AddRefs(content), &appendContent,
|
||||||
FROM_PARSER_NETWORK);
|
FROM_PARSER_NETWORK);
|
||||||
NS_ENSURE_SUCCESS(result, result);
|
NS_ENSURE_SUCCESS(result, result);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,8 @@ protected:
|
||||||
nsIContent *aContent);
|
nsIContent *aContent);
|
||||||
virtual bool NotifyForDocElement() { return true; }
|
virtual bool NotifyForDocElement() { return true; }
|
||||||
virtual nsresult CreateElement(const char16_t** aAtts, uint32_t aAttsCount,
|
virtual nsresult CreateElement(const char16_t** aAtts, uint32_t aAttsCount,
|
||||||
mozilla::dom::NodeInfo* aNodeInfo, uint32_t aLineNumber,
|
mozilla::dom::NodeInfo* aNodeInfo,
|
||||||
|
uint32_t aLineNumber, uint32_t aColumnNumber,
|
||||||
nsIContent** aResult, bool* aAppendContent,
|
nsIContent** aResult, bool* aAppendContent,
|
||||||
mozilla::dom::FromParser aFromParser);
|
mozilla::dom::FromParser aFromParser);
|
||||||
|
|
||||||
|
|
@ -161,7 +162,7 @@ protected:
|
||||||
|
|
||||||
nsresult HandleStartElement(const char16_t *aName, const char16_t **aAtts,
|
nsresult HandleStartElement(const char16_t *aName, const char16_t **aAtts,
|
||||||
uint32_t aAttsCount, uint32_t aLineNumber,
|
uint32_t aAttsCount, uint32_t aLineNumber,
|
||||||
bool aInterruptable);
|
uint32_t aColumnNumber, bool aInterruptable);
|
||||||
nsresult HandleEndElement(const char16_t *aName, bool aInterruptable);
|
nsresult HandleEndElement(const char16_t *aName, bool aInterruptable);
|
||||||
nsresult HandleCharacterData(const char16_t *aData, uint32_t aLength,
|
nsresult HandleCharacterData(const char16_t *aData, uint32_t aLength,
|
||||||
bool aInterruptable);
|
bool aInterruptable);
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,8 @@ protected:
|
||||||
nsIAtom* aTagName,
|
nsIAtom* aTagName,
|
||||||
nsIContent* aContent) override;
|
nsIContent* aContent) override;
|
||||||
virtual nsresult CreateElement(const char16_t** aAtts, uint32_t aAttsCount,
|
virtual nsresult CreateElement(const char16_t** aAtts, uint32_t aAttsCount,
|
||||||
mozilla::dom::NodeInfo* aNodeInfo, uint32_t aLineNumber,
|
mozilla::dom::NodeInfo* aNodeInfo,
|
||||||
|
uint32_t aLineNumber, uint32_t aColumnNumber,
|
||||||
nsIContent** aResult, bool* aAppendContent,
|
nsIContent** aResult, bool* aAppendContent,
|
||||||
mozilla::dom::FromParser aFromParser) override;
|
mozilla::dom::FromParser aFromParser) override;
|
||||||
virtual nsresult CloseElement(nsIContent* aContent) override;
|
virtual nsresult CloseElement(nsIContent* aContent) override;
|
||||||
|
|
@ -199,7 +200,8 @@ nsXMLFragmentContentSink::SetDocElement(int32_t aNameSpaceID,
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsXMLFragmentContentSink::CreateElement(const char16_t** aAtts, uint32_t aAttsCount,
|
nsXMLFragmentContentSink::CreateElement(const char16_t** aAtts, uint32_t aAttsCount,
|
||||||
mozilla::dom::NodeInfo* aNodeInfo, uint32_t aLineNumber,
|
mozilla::dom::NodeInfo* aNodeInfo,
|
||||||
|
uint32_t aLineNumber, uint32_t aColumnNumber,
|
||||||
nsIContent** aResult, bool* aAppendContent,
|
nsIContent** aResult, bool* aAppendContent,
|
||||||
FromParser /*aFromParser*/)
|
FromParser /*aFromParser*/)
|
||||||
{
|
{
|
||||||
|
|
@ -207,6 +209,7 @@ nsXMLFragmentContentSink::CreateElement(const char16_t** aAtts, uint32_t aAttsCo
|
||||||
// fancy CloseElement stuff.
|
// fancy CloseElement stuff.
|
||||||
nsresult rv = nsXMLContentSink::CreateElement(aAtts, aAttsCount,
|
nsresult rv = nsXMLContentSink::CreateElement(aAtts, aAttsCount,
|
||||||
aNodeInfo, aLineNumber,
|
aNodeInfo, aLineNumber,
|
||||||
|
aColumnNumber,
|
||||||
aResult, aAppendContent,
|
aResult, aAppendContent,
|
||||||
NOT_FROM_PARSER);
|
NOT_FROM_PARSER);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,8 @@ NS_IMETHODIMP
|
||||||
txStylesheetSink::HandleStartElement(const char16_t *aName,
|
txStylesheetSink::HandleStartElement(const char16_t *aName,
|
||||||
const char16_t **aAtts,
|
const char16_t **aAtts,
|
||||||
uint32_t aAttsCount,
|
uint32_t aAttsCount,
|
||||||
uint32_t aLineNumber)
|
uint32_t aLineNumber,
|
||||||
|
uint32_t aColumnNumber)
|
||||||
{
|
{
|
||||||
NS_PRECONDITION(aAttsCount % 2 == 0, "incorrect aAttsCount");
|
NS_PRECONDITION(aAttsCount % 2 == 0, "incorrect aAttsCount");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -437,7 +437,8 @@ NS_IMETHODIMP
|
||||||
XULContentSinkImpl::HandleStartElement(const char16_t *aName,
|
XULContentSinkImpl::HandleStartElement(const char16_t *aName,
|
||||||
const char16_t **aAtts,
|
const char16_t **aAtts,
|
||||||
uint32_t aAttsCount,
|
uint32_t aAttsCount,
|
||||||
uint32_t aLineNumber)
|
uint32_t aLineNumber,
|
||||||
|
uint32_t aColumnNumber)
|
||||||
{
|
{
|
||||||
// XXX Hopefully the parser will flag this before we get here. If
|
// XXX Hopefully the parser will flag this before we get here. If
|
||||||
// we're in the epilog, there should be no new elements
|
// we're in the epilog, there should be no new elements
|
||||||
|
|
@ -694,7 +695,7 @@ XULContentSinkImpl::ReportError(const char16_t* aErrorText,
|
||||||
parsererror.Append((char16_t)0xFFFF);
|
parsererror.Append((char16_t)0xFFFF);
|
||||||
parsererror.AppendLiteral("parsererror");
|
parsererror.AppendLiteral("parsererror");
|
||||||
|
|
||||||
rv = HandleStartElement(parsererror.get(), noAtts, 0, 0);
|
rv = HandleStartElement(parsererror.get(), noAtts, 0, 0, 0);
|
||||||
NS_ENSURE_SUCCESS(rv,rv);
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
|
||||||
rv = HandleCharacterData(aErrorText, NS_strlen(aErrorText));
|
rv = HandleCharacterData(aErrorText, NS_strlen(aErrorText));
|
||||||
|
|
@ -704,7 +705,7 @@ XULContentSinkImpl::ReportError(const char16_t* aErrorText,
|
||||||
sourcetext.Append((char16_t)0xFFFF);
|
sourcetext.Append((char16_t)0xFFFF);
|
||||||
sourcetext.AppendLiteral("sourcetext");
|
sourcetext.AppendLiteral("sourcetext");
|
||||||
|
|
||||||
rv = HandleStartElement(sourcetext.get(), noAtts, 0, 0);
|
rv = HandleStartElement(sourcetext.get(), noAtts, 0, 0, 0);
|
||||||
NS_ENSURE_SUCCESS(rv,rv);
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
|
||||||
rv = HandleCharacterData(aSourceText, NS_strlen(aSourceText));
|
rv = HandleCharacterData(aSourceText, NS_strlen(aSourceText));
|
||||||
|
|
|
||||||
|
|
@ -64,10 +64,10 @@ typedef bool
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Used to check if a CSP instance wants to disable eval() and friends.
|
* Used to check if a CSP instance wants to disable eval() and friends.
|
||||||
* See js_CheckCSPPermitsJSAction() in jsobj.
|
* See GlobalObject::isRuntimeCodeGenEnabled() in vm/GlobalObject.cpp.
|
||||||
*/
|
*/
|
||||||
typedef bool
|
typedef bool
|
||||||
(* JSCSPEvalChecker)(JSContext* cx);
|
(* JSCSPEvalChecker)(JSContext* cx, JS::HandleValue aValue);
|
||||||
|
|
||||||
struct JSSecurityCallbacks {
|
struct JSSecurityCallbacks {
|
||||||
JSCSPEvalChecker contentSecurityPolicyAllows;
|
JSCSPEvalChecker contentSecurityPolicyAllows;
|
||||||
|
|
|
||||||
|
|
@ -227,7 +227,7 @@ EvalKernel(JSContext* cx, HandleValue v, EvalType evalType, AbstractFramePtr cal
|
||||||
AssertInnerizedEnvironmentChain(cx, *env);
|
AssertInnerizedEnvironmentChain(cx, *env);
|
||||||
|
|
||||||
Rooted<GlobalObject*> envGlobal(cx, &env->global());
|
Rooted<GlobalObject*> envGlobal(cx, &env->global());
|
||||||
if (!GlobalObject::isRuntimeCodeGenEnabled(cx, envGlobal)) {
|
if (!GlobalObject::isRuntimeCodeGenEnabled(cx, v, envGlobal)) {
|
||||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CSP_BLOCKED_EVAL);
|
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CSP_BLOCKED_EVAL);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -330,7 +330,8 @@ js::DirectEvalStringFromIon(JSContext* cx,
|
||||||
AssertInnerizedEnvironmentChain(cx, *env);
|
AssertInnerizedEnvironmentChain(cx, *env);
|
||||||
|
|
||||||
Rooted<GlobalObject*> envGlobal(cx, &env->global());
|
Rooted<GlobalObject*> envGlobal(cx, &env->global());
|
||||||
if (!GlobalObject::isRuntimeCodeGenEnabled(cx, envGlobal)) {
|
RootedValue v(cx, StringValue(str));
|
||||||
|
if (!GlobalObject::isRuntimeCodeGenEnabled(cx, v, envGlobal)) {
|
||||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CSP_BLOCKED_EVAL);
|
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CSP_BLOCKED_EVAL);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1625,13 +1625,6 @@ static bool
|
||||||
FunctionConstructor(JSContext* cx, const CallArgs& args, GeneratorKind generatorKind,
|
FunctionConstructor(JSContext* cx, const CallArgs& args, GeneratorKind generatorKind,
|
||||||
FunctionAsyncKind asyncKind)
|
FunctionAsyncKind asyncKind)
|
||||||
{
|
{
|
||||||
// Block this call if security callbacks forbid it.
|
|
||||||
Rooted<GlobalObject*> global(cx, &args.callee().global());
|
|
||||||
if (!GlobalObject::isRuntimeCodeGenEnabled(cx, global)) {
|
|
||||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CSP_BLOCKED_FUNCTION);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isStarGenerator = generatorKind == StarGenerator;
|
bool isStarGenerator = generatorKind == StarGenerator;
|
||||||
bool isAsync = asyncKind == AsyncFunction;
|
bool isAsync = asyncKind == AsyncFunction;
|
||||||
MOZ_ASSERT(generatorKind != LegacyGenerator);
|
MOZ_ASSERT(generatorKind != LegacyGenerator);
|
||||||
|
|
@ -1733,6 +1726,14 @@ FunctionConstructor(JSContext* cx, const CallArgs& args, GeneratorKind generator
|
||||||
if (!functionText)
|
if (!functionText)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Block this call if security callbacks forbid it.
|
||||||
|
Rooted<GlobalObject*> global(cx, &args.callee().global());
|
||||||
|
RootedValue v(cx, StringValue(functionText));
|
||||||
|
if (!GlobalObject::isRuntimeCodeGenEnabled(cx, v, global)) {
|
||||||
|
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CSP_BLOCKED_FUNCTION);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NB: (new Function) is not lexically closed by its caller, it's just an
|
* NB: (new Function) is not lexically closed by its caller, it's just an
|
||||||
* anonymous function in the top-level scope that its constructor inhabits.
|
* anonymous function in the top-level scope that its constructor inhabits.
|
||||||
|
|
|
||||||
|
|
@ -543,17 +543,23 @@ GlobalObject::initSelfHostingBuiltins(JSContext* cx, Handle<GlobalObject*> globa
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ bool
|
/* static */ bool
|
||||||
GlobalObject::isRuntimeCodeGenEnabled(JSContext* cx, Handle<GlobalObject*> global)
|
GlobalObject::isRuntimeCodeGenEnabled(JSContext* cx, HandleValue code,
|
||||||
|
Handle<GlobalObject*> global)
|
||||||
{
|
{
|
||||||
HeapSlot& v = global->getSlotRef(RUNTIME_CODEGEN_ENABLED);
|
HeapSlot& v = global->getSlotRef(RUNTIME_CODEGEN_ENABLED);
|
||||||
if (v.isUndefined()) {
|
if (v.isUndefined()) {
|
||||||
/*
|
/*
|
||||||
* If there are callbacks, make sure that the CSP callback is installed
|
* If there are callbacks, make sure that the CSP callback is installed
|
||||||
* and that it permits runtime code generation, then cache the result.
|
* and that it permits runtime code generation.
|
||||||
*/
|
*/
|
||||||
JSCSPEvalChecker allows = cx->runtime()->securityCallbacks->contentSecurityPolicyAllows;
|
JSCSPEvalChecker allows = cx->runtime()->securityCallbacks->contentSecurityPolicyAllows;
|
||||||
Value boolValue = BooleanValue(!allows || allows(cx));
|
if (allows)
|
||||||
v.set(global, HeapSlot::Slot, RUNTIME_CODEGEN_ENABLED, boolValue);
|
return allows(cx, code);
|
||||||
|
|
||||||
|
// Let's cache the result only if the contentSecurityPolicyAllows callback is not set. In
|
||||||
|
// this way, contentSecurityPolicyAllows callback is executed each time, with the current
|
||||||
|
// HandleValue code.
|
||||||
|
v.set(global, HeapSlot::Slot, RUNTIME_CODEGEN_ENABLED, JS::TrueValue());
|
||||||
}
|
}
|
||||||
return !v.isFalse();
|
return !v.isFalse();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -803,7 +803,8 @@ class GlobalObject : public NativeObject
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline Value createArrayFromBuffer() const;
|
inline Value createArrayFromBuffer() const;
|
||||||
|
|
||||||
static bool isRuntimeCodeGenEnabled(JSContext* cx, Handle<GlobalObject*> global);
|
static bool isRuntimeCodeGenEnabled(JSContext* cx, HandleValue code,
|
||||||
|
Handle<GlobalObject*> global);
|
||||||
|
|
||||||
// Warn about use of the deprecated watch/unwatch functions in the global
|
// Warn about use of the deprecated watch/unwatch functions in the global
|
||||||
// in which |obj| was created, if no prior warning was given.
|
// in which |obj| was created, if no prior warning was given.
|
||||||
|
|
|
||||||
|
|
@ -955,7 +955,7 @@ SheetLoadData::OnStreamComplete(nsIUnicharStreamLoader* aLoader,
|
||||||
csp->LogViolationDetails(
|
csp->LogViolationDetails(
|
||||||
nsIContentSecurityPolicy::VIOLATION_TYPE_REQUIRE_SRI_FOR_STYLE,
|
nsIContentSecurityPolicy::VIOLATION_TYPE_REQUIRE_SRI_FOR_STYLE,
|
||||||
NS_ConvertUTF8toUTF16(spec), EmptyString(),
|
NS_ConvertUTF8toUTF16(spec), EmptyString(),
|
||||||
0, EmptyString(), EmptyString());
|
0, 0, EmptyString(), EmptyString());
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -739,6 +739,7 @@ nsStyleUtil::CSPAllowsInlineStyle(nsIContent* aContent,
|
||||||
nsIPrincipal* aPrincipal,
|
nsIPrincipal* aPrincipal,
|
||||||
nsIURI* aSourceURI,
|
nsIURI* aSourceURI,
|
||||||
uint32_t aLineNumber,
|
uint32_t aLineNumber,
|
||||||
|
uint32_t aColumnNumber,
|
||||||
const nsSubstring& aStyleText,
|
const nsSubstring& aStyleText,
|
||||||
nsresult* aRv)
|
nsresult* aRv)
|
||||||
{
|
{
|
||||||
|
|
@ -776,7 +777,7 @@ nsStyleUtil::CSPAllowsInlineStyle(nsIContent* aContent,
|
||||||
rv = csp->GetAllowsInline(nsIContentPolicy::TYPE_STYLESHEET,
|
rv = csp->GetAllowsInline(nsIContentPolicy::TYPE_STYLESHEET,
|
||||||
nonce,
|
nonce,
|
||||||
false, // aParserCreated only applies to scripts
|
false, // aParserCreated only applies to scripts
|
||||||
aStyleText, aLineNumber,
|
aStyleText, aLineNumber, aColumnNumber,
|
||||||
&allowInlineStyle);
|
&allowInlineStyle);
|
||||||
NS_ENSURE_SUCCESS(rv, false);
|
NS_ENSURE_SUCCESS(rv, false);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -164,6 +164,9 @@ public:
|
||||||
* @param aLineNumber
|
* @param aLineNumber
|
||||||
* Line number of inline style element in the containing document (for
|
* Line number of inline style element in the containing document (for
|
||||||
* reporting violations)
|
* reporting violations)
|
||||||
|
* @param aColumnNumber
|
||||||
|
* Column number of inline style element in the containing document (for
|
||||||
|
* reporting violations)
|
||||||
* @param aStyleText
|
* @param aStyleText
|
||||||
* Contents of the inline style element (for reporting violations)
|
* Contents of the inline style element (for reporting violations)
|
||||||
* @param aRv
|
* @param aRv
|
||||||
|
|
@ -175,6 +178,7 @@ public:
|
||||||
nsIPrincipal* aPrincipal,
|
nsIPrincipal* aPrincipal,
|
||||||
nsIURI* aSourceURI,
|
nsIURI* aSourceURI,
|
||||||
uint32_t aLineNumber,
|
uint32_t aLineNumber,
|
||||||
|
uint32_t aColumnNumber,
|
||||||
const nsSubstring& aStyleText,
|
const nsSubstring& aStyleText,
|
||||||
nsresult* aRv);
|
nsresult* aRv);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -394,7 +394,8 @@ nsExpatDriver::HandleStartElement(const char16_t *aValue,
|
||||||
|
|
||||||
nsresult rv = mSink->
|
nsresult rv = mSink->
|
||||||
HandleStartElement(aValue, aAtts, attrArrayLength,
|
HandleStartElement(aValue, aAtts, attrArrayLength,
|
||||||
XML_GetCurrentLineNumber(mExpatParser));
|
XML_GetCurrentLineNumber(mExpatParser),
|
||||||
|
XML_GetCurrentColumnNumber(mExpatParser));
|
||||||
MaybeStopParser(rv);
|
MaybeStopParser(rv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,11 +28,13 @@ interface nsIExpatSink : nsISupports
|
||||||
* present in aAtts.
|
* present in aAtts.
|
||||||
* @param aAttsCount the number of elements in aAtts.
|
* @param aAttsCount the number of elements in aAtts.
|
||||||
* @param aLineNumber the line number of the start tag in the data stream.
|
* @param aLineNumber the line number of the start tag in the data stream.
|
||||||
|
* @param aColumnNumber the column number of the start tag in the data stream.
|
||||||
*/
|
*/
|
||||||
void HandleStartElement(in wstring aName,
|
void HandleStartElement(in wstring aName,
|
||||||
[array, size_is(aAttsCount)] in wstring aAtts,
|
[array, size_is(aAttsCount)] in wstring aAtts,
|
||||||
in unsigned long aAttsCount,
|
in unsigned long aAttsCount,
|
||||||
in unsigned long aLineNumber);
|
in unsigned long aLineNumber,
|
||||||
|
in unsigned long aColumnNumber);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called to handle the closing tag of an element.
|
* Called to handle the closing tag of an element.
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,8 @@ NS_IMETHODIMP
|
||||||
nsSAXXMLReader::HandleStartElement(const char16_t *aName,
|
nsSAXXMLReader::HandleStartElement(const char16_t *aName,
|
||||||
const char16_t **aAtts,
|
const char16_t **aAtts,
|
||||||
uint32_t aAttsCount,
|
uint32_t aAttsCount,
|
||||||
uint32_t aLineNumber)
|
uint32_t aLineNumber,
|
||||||
|
uint32_t aColumnNumber)
|
||||||
{
|
{
|
||||||
if (!mContentHandler)
|
if (!mContentHandler)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
|
||||||
|
|
@ -388,8 +388,9 @@ RDFContentSinkImpl::QueryInterface(REFNSIID iid, void** result)
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
RDFContentSinkImpl::HandleStartElement(const char16_t *aName,
|
RDFContentSinkImpl::HandleStartElement(const char16_t *aName,
|
||||||
const char16_t **aAtts,
|
const char16_t **aAtts,
|
||||||
uint32_t aAttsCount,
|
uint32_t aAttsCount,
|
||||||
uint32_t aLineNumber)
|
uint32_t aLineNumber,
|
||||||
|
uint32_t aColumnNumber)
|
||||||
{
|
{
|
||||||
FlushText();
|
FlushText();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue