1
+ ( function ( parentScope ) {
2
+ /**
3
+ * DuckDuckGo Runtime Checks injected code.
4
+ * If you're reading this, you're probably trying to debug a site that is breaking due to our runtime checks.
5
+ * Please raise an issues on our GitHub repo: https://github.com/duckduckgo/content-scope-scripts/
6
+ */
7
+ function constructProxy ( scope , outputs ) {
8
+ const taintString = '__ddg_taint__'
9
+ // @ts -expect-error - Expected 2 arguments, but got 1
10
+ if ( Object . is ( scope ) ) {
11
+ // Should not happen, but just in case fail safely
12
+ console . error ( 'Runtime checks: Scope must be an object' , scope , outputs )
13
+ return scope
14
+ }
15
+ return new Proxy ( scope , {
16
+ get ( target , property , receiver ) {
17
+ const targetObj = target [ property ]
18
+ let targetOut = target
19
+ if ( typeof property === 'string' && property in outputs ) {
20
+ targetOut = outputs
21
+ }
22
+ // Reflects functions with the correct 'this' scope
23
+ if ( typeof targetObj === 'function' ) {
24
+ return ( ...args ) => {
25
+ return Reflect . apply ( targetOut [ property ] , target , args )
26
+ }
27
+ } else {
28
+ return Reflect . get ( targetOut , property , scope )
29
+ }
30
+ } ,
31
+ getOwnPropertyDescriptor ( target , property ) {
32
+ if ( typeof property === 'string' && property === taintString ) {
33
+ return { configurable : true , enumerable : false , value : true }
34
+ }
35
+ return Reflect . getOwnPropertyDescriptor ( target , property )
36
+ }
37
+ } )
38
+ }
39
+ let _ddg_b = parentScope ?. navigator ? parentScope . navigator : Object . bind ( null ) ;
40
+ let _ddg_c = "testingThisOut" ;
41
+ let _ddg_e = parentScope ?. navigator ?. mediaSession ? parentScope . navigator . mediaSession : Object . bind ( null ) ;
42
+ let _ddg_f = "playing" ;
43
+ let _ddg_h = parentScope ?. navigator ?. mediaSession ?. doesNotExist ? parentScope . navigator . mediaSession . doesNotExist : Object . bind ( null ) ;
44
+ let _ddg_j = parentScope ?. navigator ?. mediaSession ?. doesNotExist ?. depth ? parentScope . navigator . mediaSession . doesNotExist . depth : Object . bind ( null ) ;
45
+ let _ddg_l = parentScope ?. navigator ?. mediaSession ?. doesNotExist ?. depth ?. a ? parentScope . navigator . mediaSession . doesNotExist . depth . a : Object . bind ( null ) ;
46
+ let _ddg_m = "boop" ;
47
+ let _ddg_k = constructProxy ( _ddg_l , {
48
+ lot : _ddg_m
49
+ } ) ;
50
+ let _ddg_i = constructProxy ( _ddg_j , {
51
+ a : _ddg_k
52
+ } ) ;
53
+ let _ddg_g = constructProxy ( _ddg_h , {
54
+ depth : _ddg_i
55
+ } ) ;
56
+ let _ddg_d = constructProxy ( _ddg_e , {
57
+ playbackState : _ddg_f ,
58
+ doesNotExist : _ddg_g
59
+ } ) ;
60
+ let _ddg_a = constructProxy ( _ddg_b , {
61
+ userAgent : _ddg_c ,
62
+ mediaSession : _ddg_d
63
+ } ) ;
64
+ let navigator = _ddg_a ;
65
+ let _ddg_o = parentScope ?. document ? parentScope . document : Object . bind ( null ) ;
66
+ let _ddg_p = "testingThisOut" ;
67
+ let _ddg_n = constructProxy ( _ddg_o , {
68
+ cookie : _ddg_p
69
+ } ) ;
70
+ let document = _ddg_n ;
71
+ const window = constructProxy ( parentScope , {
72
+ navigator : _ddg_a ,
73
+ document : _ddg_n
74
+ } ) ;
75
+ // Ensure globalThis === window
76
+ const globalThis = window
77
+ function getContextId ( scope ) {
78
+ if ( document ?. currentScript && 'contextID' in document . currentScript ) {
79
+ return document . currentScript . contextID
80
+ }
81
+ if ( scope . contextID ) {
82
+ return scope . contextID
83
+ }
84
+ // @ts -expect-error - contextID is a global variable
85
+ if ( typeof contextID !== 'undefined' ) {
86
+ // @ts -expect-error - contextID is a global variable
87
+ // eslint-disable-next-line no-undef
88
+ return contextID
89
+ }
90
+ }
91
+ function generateUniqueID ( ) {
92
+ const debug = false
93
+ if ( debug ) {
94
+ // Easier to debug
95
+ return Symbol ( globalThis ?. crypto ?. randomUUID ( ) )
96
+ }
97
+ return Symbol ( undefined )
98
+ }
99
+ function createContextAwareFunction ( fn ) {
100
+ return function ( ...args ) {
101
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
102
+ let scope = this
103
+ // Save the previous contextID and set the new one
104
+ const prevContextID = this ?. contextID
105
+ // @ts -expect-error - contextID is undefined on window
106
+ // eslint-disable-next-line no-undef
107
+ const changeToContextID = getContextId ( this ) || contextID
108
+ if ( typeof args [ 0 ] === 'function' ) {
109
+ args [ 0 ] . contextID = changeToContextID
110
+ }
111
+ // @ts -expect-error - scope doesn't match window
112
+ if ( scope && scope !== globalThis ) {
113
+ scope . contextID = changeToContextID
114
+ } else if ( ! scope ) {
115
+ scope = new Proxy ( scope , {
116
+ get ( target , prop ) {
117
+ if ( prop === 'contextID' ) {
118
+ return changeToContextID
119
+ }
120
+ return Reflect . get ( target , prop )
121
+ }
122
+ } )
123
+ }
124
+ // Run the original function with the new contextID
125
+ const result = Reflect . apply ( fn , scope , args )
126
+ // Restore the previous contextID
127
+ scope . contextID = prevContextID
128
+ return result
129
+ }
130
+ }
131
+ function addTaint ( ) {
132
+ const contextID = generateUniqueID ( )
133
+ if ( 'duckduckgo' in navigator &&
134
+ navigator . duckduckgo &&
135
+ typeof navigator . duckduckgo === 'object' &&
136
+ 'taints' in navigator . duckduckgo &&
137
+ navigator . duckduckgo . taints instanceof Set ) {
138
+ if ( document . currentScript ) {
139
+ // @ts -expect-error - contextID is undefined on currentScript
140
+ document . currentScript . contextID = contextID
141
+ }
142
+ navigator ?. duckduckgo ?. taints . add ( contextID )
143
+ }
144
+ return contextID
145
+ }
146
+ const contextID = addTaint ( )
147
+ const originalSetTimeout = setTimeout
148
+ setTimeout = createContextAwareFunction ( originalSetTimeout )
149
+ const originalSetInterval = setInterval
150
+ setInterval = createContextAwareFunction ( originalSetInterval )
151
+ const originalPromiseThen = Promise . prototype . then
152
+ Promise . prototype . then = createContextAwareFunction ( originalPromiseThen )
153
+ const originalPromiseCatch = Promise . prototype . catch
154
+ Promise . prototype . catch = createContextAwareFunction ( originalPromiseCatch )
155
+ const originalPromiseFinally = Promise . prototype . finally
156
+ Promise . prototype . finally = createContextAwareFunction ( originalPromiseFinally )
157
+ console . log ( 1 )
158
+ } ) ( globalThis )
0 commit comments