Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add csp-violation-event-plugin #590

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
156 changes: 156 additions & 0 deletions app/csp_violation_event.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
<!DOCTYPE html>
<html>
<head>
<title>RUM Integ Test</title>
<script src="./loader_csp_violation_event.js"></script>
<link
rel="icon"
type="image/png"
href="https://awsmedia.s3.amazonaws.com/favicon.ico"
/>

<script>
// Common to all test pages
function dispatch() {
cwr('dispatch');
}

function clearRequestResponse() {
document.getElementById('request_url').innerText = '';
document.getElementById('request_header').innerText = '';
document.getElementById('request_body').innerText = '';

document.getElementById('response_status').innerText = '';
document.getElementById('response_header').innerText = '';
document.getElementById('response_body').innerText = '';
}

// Specific to ContentSecurityPolicy Violation error plugin
function triggerSecurityPolicyViolationEvent() {
const event = new Event('securitypolicyviolation');
Object.assign(event, {
violatedDirective: 'test:violatedDirective',
documentURI: 'http://documentURI',
blockedURI: 'https://blockedURI',
originalPolicy: 'test:originalPolicy',
referrer: 'test:referrer',
statusCode: 200,
effectiveDirective: 'test:effectiveDirective'
});
dispatchEvent(event);
}

function recordCspViolationEvent() {
const event = new Event('securitypolicyviolation');
Object.assign(event, {
violatedDirective: 'test:violatedDirective',
documentURI: 'http://documentURI',
blockedURI: 'https://blockedURI',
originalPolicy: 'test:originalPolicy',
referrer: 'test:referrer',
statusCode: 200,
effectiveDirective: 'test:effectiveDirective'
});

cwr('recordCspViolation', event);
}

function triggerIgnoredSecurityPolicyViolationEvent() {
const event = new Event('securitypolicyviolation');
Object.assign(event, {
violatedDirective: 'test:violatedDirective',
documentURI: 'http://ignoredDocumentURI',
blockedURI: 'https://blockedURI',
originalPolicy: 'test:originalPolicy',
referrer: 'test:referrer',
statusCode: 200,
effectiveDirective: 'test:effectiveDirective'
});
dispatchEvent(event);
}

function disable() {
cwr('disable');
}

function enable() {
cwr('enable');
}
</script>

<style>
table {
border-collapse: collapse;
margin-top: 10px;
margin-bottom: 10px;
}

td,
th {
border: 1px solid black;
text-align: left;
padding: 8px;
}
</style>
</head>
<body>
<p id="welcome">This application is used for RUM integ testing.</p>
<hr />
<button
id="triggerSecurityPolicyViolationEvent"
onclick="triggerSecurityPolicyViolationEvent()"
>
Trigger SecurityPolicyViolationEvent
</button>
<button
id="triggerIgnoredSecurityPolicyViolationEvent"
onclick="triggerIgnoredSecurityPolicyViolationEvent()"
>
Trigger IgnoredSecurityPolicyViolationEvent
</button>
<button
id="recordCspViolationEvent"
onclick="recordCspViolationEvent()"
>
Record CspViolationEvent
</button>
<button id="disable" onclick="disable()">Disable</button>
<button id="enable" onclick="enable()">Enable</button>
<hr />
<button id="dispatch" onclick="dispatch()">Dispatch</button>
<button id="clearRequestResponse" onclick="clearRequestResponse()">
Clear
</button>
<hr />
<span id="request"></span>
<span id="response"></span>
<table>
<tr>
<td>Request URL</td>
<td id="request_url"></td>
</tr>
<tr>
<td>Request Header</td>
<td id="request_header"></td>
</tr>
<tr>
<td>Request Body</td>
<td id="request_body"></td>
</tr>
</table>
<table>
<tr>
<td>Response Status Code</td>
<td id="response_status"></td>
</tr>
<tr>
<td>Response Header</td>
<td id="response_header"></td>
</tr>
<tr>
<td>Response Body</td>
<td id="response_body"></td>
</tr>
</table>
</body>
</html>
16 changes: 10 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions src/CommandQueue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ interface CommandFunctions {
addSessionAttributes: CommandFunction;
recordPageView: CommandFunction;
recordError: CommandFunction;
recordCspViolation: CommandFunction;
registerDomEvents: CommandFunction;
recordEvent: CommandFunction;
dispatch: CommandFunction;
Expand Down Expand Up @@ -68,6 +69,9 @@ export class CommandQueue {
recordError: (payload: any): void => {
this.orchestration.recordError(payload);
},
recordCspViolation: (payload: any): void => {
this.orchestration.recordCspViolation(payload);
},
registerDomEvents: (payload: any): void => {
this.orchestration.registerDomEvents(payload);
},
Expand Down
64 changes: 64 additions & 0 deletions src/event-schemas/csp-violation-event.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"$id": "com.amazon.rum.csp_violation_event",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "CspViolationEvent",
"type": "object",
"properties": {
"version": {
"const": "1.0.0",
"type": "string",
"description": "Schema version."
},
"blockedURI": {
"type": "string",
"description": "https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/blockedURI"
},
"columnNumber": {
"type": "number",
"description": "https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/columnNumber"
},
"disposition": {
"type": "string",
"enum": ["enforce", "report"],
"description": "https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/disposition"
},
"documentURI": {
"type": "string",
"description": "https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/documentURI"
},
"effectiveDirective": {
"type": "string",
"description": "https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/effectiveDirective"
},
"lineNumber": {
"type": "number",
"description": "https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/lineNumber"
},
"originalPolicy": {
"type": "string",
"description": "https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/originalPolicy"
},
"referrer": {
"type": ["string", "null"],
"description": "https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/referrer"
},
"sample": {
"type": "string",
"description": "https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/sample"
},
"sourceFile": {
"type": ["string", "null"],
"description": "https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/sourceFile"
},
"statusCode": {
"type": "number",
"description": "https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/statusCode"
},
"violatedDirective": {
"type": "string",
"description": "https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/violatedDirective"
}
},
"additionalProperties": false,
"required": ["version"]
}
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export { PageAttributes } from './sessions/PageManager';
export { Plugin } from './plugins/Plugin';
export { PluginContext } from './plugins/types';
export { TTIPlugin } from './plugins/event-plugins/TTIPlugin';
export * from './plugins/event-plugins/CspViolationPlugin';
export * from './plugins/event-plugins/DomEventPlugin';
export * from './plugins/event-plugins/JsErrorPlugin';
export * from './plugins/event-plugins/NavigationPlugin';
Expand Down
23 changes: 23 additions & 0 deletions src/loader/loader-csp-violation-event.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { loader } from './loader';
import { showRequestClientBuilder } from '../test-utils/mock-http-handler';
import { CspViolationPlugin } from '../plugins/event-plugins/CspViolationPlugin';
loader('cwr', 'abc123', '1.0', 'us-west-2', './rum_javascript_telemetry.js', {
allowCookies: true,
dispatchInterval: 0,
metaDataPluginsToLoad: [],
eventPluginsToLoad: [
new CspViolationPlugin({
ignore: (e) => {
const ignoredDocuments = ['http://ignoredDocumentURI'];
return ignoredDocuments.includes(e.documentURI);
}
})
],
telemetries: [],
clientBuilder: showRequestClientBuilder
});
window.cwr('setAwsCredentials', {
accessKeyId: 'a',
secretAccessKey: 'b',
sessionToken: 'c'
});
25 changes: 23 additions & 2 deletions src/orchestration/Orchestration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ import {
JsErrorPlugin,
JS_ERROR_EVENT_PLUGIN_ID
} from '../plugins/event-plugins/JsErrorPlugin';
import {
CspViolationPlugin,
CSP_VIOLATION_EVENT_PLUGIN_ID
} from '../plugins/event-plugins/CspViolationPlugin';

import { EventCache } from '../event-cache/EventCache';
import { ClientBuilder, Dispatch } from '../dispatch/Dispatch';
import {
Expand Down Expand Up @@ -342,6 +347,20 @@ export class Orchestration {
this.pluginManager.record(JS_ERROR_EVENT_PLUGIN_ID, error);
}

/**
* Record an SecurityPolicyViolationEvent using the CSP Violation plugin.
*
* @param securityPolicyViolationEvent a SecurityPolicyViolationEvent.
*/
public recordCspViolation(
securityPolicyViolationEvent: SecurityPolicyViolationEvent
) {
this.pluginManager.record(
CSP_VIOLATION_EVENT_PLUGIN_ID,
securityPolicyViolationEvent
);
}

/**
* Update DOM plugin to record the (additional) provided DOM events.
*
Expand Down Expand Up @@ -464,7 +483,6 @@ export class Orchestration {
];
}
});

return plugins;
}

Expand All @@ -484,7 +502,10 @@ export class Orchestration {
private telemetryFunctor(): TelemetriesFunctor {
return {
[TelemetryEnum.Errors]: (config: object): InternalPlugin[] => {
return [new JsErrorPlugin(config)];
return [
new JsErrorPlugin(config),
new CspViolationPlugin(config)
];
},
[TelemetryEnum.Performance]: (config: object): InternalPlugin[] => {
return [
Expand Down
Loading