1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef nsCSPContext_h___
8 #define nsCSPContext_h___
10 #include "mozilla/dom/nsCSPUtils.h"
11 #include "mozilla/dom/SecurityPolicyViolationEvent.h"
12 #include "mozilla/StaticPrefs_security.h"
13 #include "nsIChannel.h"
14 #include "nsIChannelEventSink.h"
15 #include "nsIContentSecurityPolicy.h"
16 #include "nsIInterfaceRequestor.h"
17 #include "nsIStreamListener.h"
18 #include "nsIWeakReferenceUtils.h"
21 #define NS_CSPCONTEXT_CONTRACTID "@mozilla.org/cspcontext;1"
22 // 09d9ed1a-e5d4-4004-bfe0-27ceb923d9ac
23 #define NS_CSPCONTEXT_CID \
25 0x09d9ed1a, 0xe5d4, 0x4004, { \
26 0xbf, 0xe0, 0x27, 0xce, 0xb9, 0x23, 0xd9, 0xac \
30 class nsINetworkInterceptController
;
32 struct ConsoleMsgQueueElem
;
39 class ContentSecurityPolicy
;
41 } // namespace mozilla
43 class nsCSPContext
: public nsIContentSecurityPolicy
{
46 NS_DECL_NSICONTENTSECURITYPOLICY
47 NS_DECL_NSISERIALIZABLE
50 virtual ~nsCSPContext();
55 static bool Equals(nsIContentSecurityPolicy
* aCSP
,
56 nsIContentSecurityPolicy
* aOtherCSP
);
58 // Init a CSP from a different CSP
59 nsresult
InitFromOther(nsCSPContext
* otherContext
);
62 * SetRequestContextWithDocument() needs to be called before the
63 * innerWindowID is initialized on the document. Use this function
64 * to call back to flush queued up console messages and initialize
65 * the innerWindowID. Node, If SetRequestContextWithPrincipal() was
66 * called then we do not have a innerWindowID anyway and hence
67 * we can not flush messages to the correct console.
69 void flushConsoleMessages();
71 void logToConsole(const char* aName
, const nsTArray
<nsString
>& aParams
,
72 const nsAString
& aSourceName
, const nsAString
& aSourceLine
,
73 uint32_t aLineNumber
, uint32_t aColumnNumber
,
74 uint32_t aSeverityFlag
);
77 * Construct SecurityPolicyViolationEventInit structure.
80 * A nsIURI: the source of the violation.
82 * The original URI if the blocked content is a redirect, else null
83 * @param aViolatedDirective
84 * the directive that was violated (string).
86 * name of the file containing the inline script violation
87 * @param aScriptSample
88 * a sample of the violating inline script
90 * source line number of the violation (if available)
92 * source column number of the violation (if available)
93 * @param aViolationEventInit
96 nsresult
GatherSecurityPolicyViolationEventData(
97 nsIURI
* aBlockedURI
, const nsACString
& aBlockedString
,
98 nsIURI
* aOriginalURI
, const nsAString
& aViolatedDirective
,
99 uint32_t aViolatedPolicyIndex
, const nsAString
& aSourceFile
,
100 const nsAString
& aScriptSample
, uint32_t aLineNum
, uint32_t aColumnNum
,
101 mozilla::dom::SecurityPolicyViolationEventInit
& aViolationEventInit
);
103 nsresult
SendReports(
104 const mozilla::dom::SecurityPolicyViolationEventInit
& aViolationEventInit
,
105 uint32_t aViolatedPolicyIndex
);
107 nsresult
FireViolationEvent(
108 mozilla::dom::Element
* aTriggeringElement
,
109 nsICSPEventListener
* aCSPEventListener
,
110 const mozilla::dom::SecurityPolicyViolationEventInit
&
111 aViolationEventInit
);
113 enum BlockedContentSource
{
121 nsresult
AsyncReportViolation(
122 mozilla::dom::Element
* aTriggeringElement
,
123 nsICSPEventListener
* aCSPEventListener
, nsIURI
* aBlockedURI
,
124 BlockedContentSource aBlockedContentSource
, nsIURI
* aOriginalURI
,
125 const nsAString
& aViolatedDirective
, const nsAString
& aEffectiveDirective
,
126 uint32_t aViolatedPolicyIndex
, const nsAString
& aObserverSubject
,
127 const nsAString
& aSourceFile
, const nsAString
& aScriptSample
,
128 uint32_t aLineNum
, uint32_t aColumnNum
);
130 // Hands off! Don't call this method unless you know what you
131 // are doing. It's only supposed to be called from within
132 // the principal destructor to avoid a tangling pointer.
133 void clearLoadingPrincipal() { mLoadingPrincipal
= nullptr; }
135 nsWeakPtr
GetLoadingContext() { return mLoadingContext
; }
137 static uint32_t ScriptSampleMaxLength() {
139 mozilla::StaticPrefs::security_csp_reporting_script_sample_max_length(),
143 void AddIPCPolicy(const mozilla::ipc::ContentSecurityPolicy
& aPolicy
);
144 void SerializePolicies(
145 nsTArray
<mozilla::ipc::ContentSecurityPolicy
>& aPolicies
);
148 void EnsureIPCPoliciesRead();
150 bool permitsInternal(CSPDirective aDir
,
151 mozilla::dom::Element
* aTriggeringElement
,
152 nsICSPEventListener
* aCSPEventListener
,
153 nsIURI
* aContentLocation
, nsIURI
* aOriginalURIIfRedirect
,
154 const nsAString
& aNonce
, bool aSpecific
,
155 bool aSendViolationReports
,
156 bool aSendContentLocationInViolationReports
,
157 bool aParserCreated
);
159 // helper to report inline script/style violations
160 void reportInlineViolation(CSPDirective aDirective
,
161 mozilla::dom::Element
* aTriggeringElement
,
162 nsICSPEventListener
* aCSPEventListener
,
163 const nsAString
& aNonce
, const nsAString
& aContent
,
164 const nsAString
& aViolatedDirective
,
165 const nsAString
& aEffectiveDirective
,
166 uint32_t aViolatedPolicyIndex
,
167 uint32_t aLineNumber
, uint32_t aColumnNumber
);
170 uint64_t mInnerWindowID
; // used for web console logging
171 bool mSkipAllowInlineStyleCheck
; // used to allow Devtools to edit styles
172 // When deserializing an nsCSPContext instance, we initially just keep the
173 // policies unparsed. We will only reconstruct actual CSP policy instances
174 // when there's an attempt to use the CSP. Given a better way to serialize/
175 // deserialize individual nsCSPPolicy objects, this performance
176 // optimization could go away.
177 nsTArray
<mozilla::ipc::ContentSecurityPolicy
> mIPCPolicies
;
178 nsTArray
<nsCSPPolicy
*> mPolicies
;
179 nsCOMPtr
<nsIURI
> mSelfURI
;
180 nsCOMPtr
<nsILoadGroup
> mCallingChannelLoadGroup
;
181 nsWeakPtr mLoadingContext
;
182 nsCOMPtr
<nsIPrincipal
> mLoadingPrincipal
;
184 // helper members used to queue up web console messages till
185 // the windowID becomes available. see flushConsoleMessages()
186 nsTArray
<ConsoleMsgQueueElem
> mConsoleMsgQueue
;
187 bool mQueueUpMessages
;
188 nsCOMPtr
<nsIEventTarget
> mEventTarget
;
191 // Class that listens to violation report transmission and logs errors.
192 class CSPViolationReportListener
: public nsIStreamListener
{
194 NS_DECL_NSISTREAMLISTENER
195 NS_DECL_NSIREQUESTOBSERVER
199 CSPViolationReportListener();
202 virtual ~CSPViolationReportListener();
205 // The POST of the violation report (if it happens) should not follow
206 // redirects, per the spec. hence, we implement an nsIChannelEventSink
207 // with an object so we can tell XHR to abort if a redirect happens.
208 class CSPReportRedirectSink final
: public nsIChannelEventSink
,
209 public nsIInterfaceRequestor
{
211 NS_DECL_NSICHANNELEVENTSINK
212 NS_DECL_NSIINTERFACEREQUESTOR
216 CSPReportRedirectSink();
218 void SetInterceptController(
219 nsINetworkInterceptController
* aInterceptController
);
222 virtual ~CSPReportRedirectSink();
225 nsCOMPtr
<nsINetworkInterceptController
> mInterceptController
;
228 #endif /* nsCSPContext_h___ */