summaryrefslogtreecommitdiff
path: root/data/extensions/jsr@javascriptrestrictor/wrappingS-PT2.js
blob: 1f304b42322f03215ed91cbcc86d2ce3166ff539 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/** \file
 * \brief Wrappers for Performance Timeline (Level 2) standard
 *
 * \see https://w3c.github.io/performance-timeline
 *
 *  \author Copyright (C) 2019  Libor Polcak
 *  \author Copyright (C) 2020  Peter Hornak
 *
 *  \license SPDX-License-Identifier: GPL-3.0-or-later
 */
//
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <https://www.gnu.org/licenses/>.
//


/** \file
 * \ingroup wrappers
 *
 * This wrapper aims on prevention of microarchitectural attacks, clock-skew attacks, and other time
 * related attacks. The goal is to limit the precision of the time returned by the Performance Timeline API.
 *
 * \see https://www.fit.vut.cz/study/thesis/22308/?year=0&sup=Pol%C4%8D%C3%A1k, especially Sect.
 * 7.2.
 *
 * \see Tom Van Goethem, Wouter Joosen, Nick Nikiforakis. The Clock is Still Ticking:
Timing Attacks in the Modern Web. CCS'15. DOI: http://dx.doi.org/10.1145/2810103.2813632.
https://lirias.kuleuven.be/retrieve/389086
 *
 * \see Schwarz, M., Lipp, M. a Gruss, D. JavaScript Zero: Real JavaScript and Zero
 *      Side-Channel Attacks. NDSS'18.
 *
 * \see Schwarz M., Maurice C., Gruss D., Mangard S. (2017) Fantastic Timers and Where to Find Them: High-Resolution Microarchitectural Attacks in JavaScript. In: Kiayias A. (eds) Financial Cryptography and Data Security. FC 2017. Lecture Notes in Computer Science, vol 10322. Springer, Cham. https://doi.org/10.1007/978-3-319-70972-7_13 
 *
 * The wrappers support the following behaviour:
 *
 * * Round timestamp: Limit the precision by removing (a part of) the decimal part of the timestamp.
 * * Randomize after rounding: Create a fake decimal part to confuse attackers and to create
 *   timestamps that look similar to expected timestamps.
 */


/*
 * Create private namespace
 */
(function() {
	var helping_code = `var precision = args[0];
	var doNoise = args[1];
	var pastValues = {};
	${rounding_function}
	${noise_function}
				var func = rounding_function;
				if (doNoise === true){
					func = function(value, precision) {
						let params = [value, precision];
						if (params in pastValues) {
							return pastValues[params];
						}
						let result = noise_function(...params);
						pastValues[params] = result;
						return result;
					}
				}
			`;

	var wrappers = [
		{
			parent_object: "PerformanceEntry",
			parent_object_property: "prototype",
			wrapped_objects: [],
			helping_code: helping_code,
			post_wrapping_code: [
				{
					code_type: "object_properties",
					parent_object: "PerformanceEntry.prototype",
					parent_object_property: "startTime",
					wrapped_objects: [
						{
							original_name: "Object.getOwnPropertyDescriptor(PerformanceEntry.prototype, 'startTime')['get']",
							wrapped_name: "originalST",
						},
					],
					wrapped_properties: [
						{
							property_name: "get",
							property_value: `
								function() {
									let originalVal = originalST.call(this, ...arguments);
									return func(originalVal, precision);
								}`,
						},
					],
				},
				{
					code_type: "object_properties",
					parent_object: "PerformanceEntry.prototype",
					parent_object_property: "duration",
					wrapped_objects: [
						{
							original_name: "Object.getOwnPropertyDescriptor(PerformanceEntry.prototype, 'duration')['get']",
							wrapped_name: "originalD",
						},
					],
					wrapped_properties: [
						{
							property_name: "get",
							property_value: `
								function() {
									let originalVal = originalD.call(this, ...arguments);
									return func(this.startTime + originalVal, precision) - this.startTime;
								}`,
						},
					],
				},
				{
					code_type: "object_properties",
					parent_object: "PerformanceEntry.prototype",
					parent_object_property: "toJSON",
					wrapped_objects: [],
					wrapped_properties: [
						{
							property_name: "value",
							property_value: `
								function() {
									let res = {
										entryType: this.entryType,
										name: this.name,
										startTime: this.startTime,
										duration: this.duration,
										toJSON: function() {return this},
									};
									return res.toJSON();
								}`,
						},
					],
				},
			],
		},
	]
	add_wrappers(wrappers);
})();