Skip to content

Commit 4103667

Browse files
authored
feat(core): Add raw_security envelope types (#14562)
Adds types for the `raw_security` envelope type. These are displayed in Sentry as CSP violations.
1 parent 045d8b4 commit 4103667

File tree

5 files changed

+54
-2
lines changed

5 files changed

+54
-2
lines changed

packages/core/src/envelope.ts

+27
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import type {
77
Event,
88
EventEnvelope,
99
EventItem,
10+
LegacyCSPReport,
11+
RawSecurityEnvelope,
12+
RawSecurityItem,
1013
SdkInfo,
1114
SdkMetadata,
1215
Session,
@@ -24,6 +27,7 @@ import {
2427
createSpanEnvelopeItem,
2528
getSdkMetadataForEnvelopeHeader,
2629
} from './utils-hoist/envelope';
30+
import { uuid4 } from './utils-hoist/misc';
2731
import { showSpanDropWarning, spanToJSON } from './utils/spanUtils';
2832

2933
/**
@@ -141,3 +145,26 @@ export function createSpanEnvelope(spans: [SentrySpan, ...SentrySpan[]], client?
141145

142146
return createEnvelope<SpanEnvelope>(headers, items);
143147
}
148+
149+
/**
150+
* Create an Envelope from a CSP report.
151+
*/
152+
export function createRawSecurityEnvelope(
153+
report: LegacyCSPReport,
154+
dsn: DsnComponents,
155+
tunnel?: string,
156+
release?: string,
157+
environment?: string,
158+
): RawSecurityEnvelope {
159+
const envelopeHeaders = {
160+
event_id: uuid4(),
161+
...(!!tunnel && dsn && { dsn: dsnToString(dsn) }),
162+
};
163+
164+
const eventItem: RawSecurityItem = [
165+
{ type: 'raw_security', sentry_release: release, sentry_environment: environment },
166+
report,
167+
];
168+
169+
return createEnvelope<RawSecurityEnvelope>(envelopeHeaders, [eventItem]);
170+
}

packages/core/src/types-hoist/csp.ts

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
export interface LegacyCSPReport {
2+
readonly 'csp-report': {
3+
readonly 'document-uri'?: string;
4+
readonly referrer?: string;
5+
readonly 'blocked-uri'?: string;
6+
readonly 'effective-directive'?: string;
7+
readonly 'violated-directive'?: string;
8+
readonly 'original-policy'?: string;
9+
readonly disposition: 'enforce' | 'report' | 'reporting';
10+
readonly 'status-code'?: number;
11+
readonly status?: string;
12+
readonly 'script-sample'?: string;
13+
readonly sample?: string;
14+
};
15+
}

packages/core/src/types-hoist/envelope.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { AttachmentType } from './attachment';
22
import type { SerializedCheckIn } from './checkin';
33
import type { ClientReport } from './clientreport';
4+
import type { LegacyCSPReport } from './csp';
45
import type { DsnComponents } from './dsn';
56
import type { Event } from './event';
67
import type { FeedbackEvent, UserFeedback } from './feedback';
@@ -41,7 +42,8 @@ export type EnvelopeItemType =
4142
| 'replay_recording'
4243
| 'check_in'
4344
| 'statsd'
44-
| 'span';
45+
| 'span'
46+
| 'raw_security';
4547

4648
export type BaseEnvelopeHeaders = {
4749
[key: string]: unknown;
@@ -84,6 +86,7 @@ type ProfileItemHeaders = { type: 'profile' };
8486
type ProfileChunkItemHeaders = { type: 'profile_chunk' };
8587
type StatsdItemHeaders = { type: 'statsd'; length: number };
8688
type SpanItemHeaders = { type: 'span' };
89+
type RawSecurityHeaders = { type: 'raw_security'; sentry_release?: string; sentry_environment?: string };
8790

8891
export type EventItem = BaseEnvelopeItem<EventItemHeaders, Event>;
8992
export type AttachmentItem = BaseEnvelopeItem<AttachmentItemHeaders, string | Uint8Array>;
@@ -100,6 +103,7 @@ export type FeedbackItem = BaseEnvelopeItem<FeedbackItemHeaders, FeedbackEvent>;
100103
export type ProfileItem = BaseEnvelopeItem<ProfileItemHeaders, Profile>;
101104
export type ProfileChunkItem = BaseEnvelopeItem<ProfileChunkItemHeaders, ProfileChunk>;
102105
export type SpanItem = BaseEnvelopeItem<SpanItemHeaders, Partial<SpanJSON>>;
106+
export type RawSecurityItem = BaseEnvelopeItem<RawSecurityHeaders, LegacyCSPReport>;
103107

104108
export type EventEnvelopeHeaders = { event_id: string; sent_at: string; trace?: Partial<DynamicSamplingContext> };
105109
type SessionEnvelopeHeaders = { sent_at: string };
@@ -120,6 +124,7 @@ export type CheckInEnvelope = BaseEnvelope<CheckInEnvelopeHeaders, CheckInItem>;
120124
export type StatsdEnvelope = BaseEnvelope<StatsdEnvelopeHeaders, StatsdItem>;
121125
export type SpanEnvelope = BaseEnvelope<SpanEnvelopeHeaders, SpanItem>;
122126
export type ProfileChunkEnvelope = BaseEnvelope<BaseEnvelopeHeaders, ProfileChunkItem>;
127+
export type RawSecurityEnvelope = BaseEnvelope<BaseEnvelopeHeaders, RawSecurityItem>;
123128

124129
export type Envelope =
125130
| EventEnvelope
@@ -129,6 +134,7 @@ export type Envelope =
129134
| ReplayEnvelope
130135
| CheckInEnvelope
131136
| StatsdEnvelope
132-
| SpanEnvelope;
137+
| SpanEnvelope
138+
| RawSecurityEnvelope;
133139

134140
export type EnvelopeItem = Envelope[1][number];

packages/core/src/types-hoist/index.ts

+3
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ export type {
4343
UserFeedbackItem,
4444
CheckInItem,
4545
CheckInEnvelope,
46+
RawSecurityEnvelope,
47+
RawSecurityItem,
4648
StatsdItem,
4749
StatsdEnvelope,
4850
ProfileItem,
@@ -182,3 +184,4 @@ export type {
182184
export type { ParameterizedString } from './parameterize';
183185
export type { ContinuousProfiler, ProfilingIntegration, Profiler } from './profiling';
184186
export type { ViewHierarchyData, ViewHierarchyWindow } from './view-hierarchy';
187+
export type { LegacyCSPReport } from './csp';

packages/core/src/utils-hoist/envelope.ts

+1
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ const ITEM_TYPE_TO_DATA_CATEGORY_MAP: Record<EnvelopeItemType, DataCategory> = {
224224
feedback: 'feedback',
225225
span: 'span',
226226
statsd: 'metric_bucket',
227+
raw_security: 'security',
227228
};
228229

229230
/**

0 commit comments

Comments
 (0)