Deny third-party cookie creation for prevalent resources without interaction
[WebKit-https.git] / Source / WebKit / UIProcess / WebResourceLoadStatisticsStore.h
1 /*
2  * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #pragma once
27
28 #include "Connection.h"
29 #include "ResourceLoadStatisticsClassifier.h"
30 #include "ResourceLoadStatisticsPersistentStorage.h"
31 #include "WebsiteDataType.h"
32 #include <wtf/MonotonicTime.h>
33 #include <wtf/RunLoop.h>
34 #include <wtf/Vector.h>
35 #include <wtf/WallTime.h>
36 #include <wtf/text/WTFString.h>
37
38 #if HAVE(CORE_PREDICTION)
39 #include "ResourceLoadStatisticsClassifierCocoa.h"
40 #endif
41
42 namespace WTF {
43 class WorkQueue;
44 }
45
46 namespace WebCore {
47 class KeyedDecoder;
48 class KeyedEncoder;
49 class URL;
50 struct ResourceLoadStatistics;
51 }
52
53 namespace WebKit {
54
55 class OperatingDate;
56 class WebProcessProxy;
57
58 enum class ShouldClearFirst;
59
60 class WebResourceLoadStatisticsStore final : public IPC::Connection::WorkQueueMessageReceiver {
61 public:
62     using UpdatePrevalentDomainsWithAndWithoutInteractionHandler = WTF::Function<void(const Vector<String>& domainsWithInteraction, const Vector<String>& domainsWithoutInteraction, ShouldClearFirst)>;
63     using RemovePrevalentDomainsHandler = WTF::Function<void (const Vector<String>&)>;
64     static Ref<WebResourceLoadStatisticsStore> create(const String& resourceLoadStatisticsDirectory, Function<void (const String&)>&& testingCallback, UpdatePrevalentDomainsWithAndWithoutInteractionHandler&& updateCookiePartitioningForDomainsHandler = [](const Vector<String>&, const Vector<String>&, ShouldClearFirst) { }, RemovePrevalentDomainsHandler&& removeDomainsHandler = [] (const Vector<String>&) { })
65     {
66         return adoptRef(*new WebResourceLoadStatisticsStore(resourceLoadStatisticsDirectory, WTFMove(testingCallback), WTFMove(updateCookiePartitioningForDomainsHandler), WTFMove(removeDomainsHandler)));
67     }
68
69     ~WebResourceLoadStatisticsStore();
70
71     static const OptionSet<WebsiteDataType>& monitoredDataTypes();
72
73     bool isEmpty() const { return m_resourceStatisticsMap.isEmpty(); }
74     WorkQueue& statisticsQueue() { return m_statisticsQueue.get(); }
75
76     void setNotifyPagesWhenDataRecordsWereScanned(bool value) { m_parameters.shouldNotifyPagesWhenDataRecordsWereScanned = value; }
77     void setShouldClassifyResourcesBeforeDataRecordsRemoval(bool value) { m_parameters.shouldClassifyResourcesBeforeDataRecordsRemoval = value; }
78     void setShouldSubmitTelemetry(bool value) { m_parameters.shouldSubmitTelemetry = value; }
79
80     void resourceLoadStatisticsUpdated(Vector<WebCore::ResourceLoadStatistics>&& origins);
81
82     void processWillOpenConnection(WebProcessProxy&, IPC::Connection&);
83     void processDidCloseConnection(WebProcessProxy&, IPC::Connection&);
84     void applicationWillTerminate();
85
86     void logUserInteraction(const WebCore::URL&);
87     void clearUserInteraction(const WebCore::URL&);
88     void hasHadUserInteraction(const WebCore::URL&, WTF::Function<void (bool)>&&);
89     void setLastSeen(const WebCore::URL&, Seconds);
90     void setPrevalentResource(const WebCore::URL&);
91     void isPrevalentResource(const WebCore::URL&, WTF::Function<void (bool)>&&);
92     void clearPrevalentResource(const WebCore::URL&);
93     void setGrandfathered(const WebCore::URL&, bool);
94     void isGrandfathered(const WebCore::URL&, WTF::Function<void (bool)>&&);
95     void setSubframeUnderTopFrameOrigin(const WebCore::URL& subframe, const WebCore::URL& topFrame);
96     void setSubresourceUnderTopFrameOrigin(const WebCore::URL& subresource, const WebCore::URL& topFrame);
97     void setSubresourceUniqueRedirectTo(const WebCore::URL& subresource, const WebCore::URL& hostNameRedirectedTo);
98     void scheduleCookiePartitioningUpdate();
99     void scheduleCookiePartitioningUpdateForDomains(const Vector<String>& domainsToRemove, const Vector<String>& domainsToAdd, ShouldClearFirst);
100     void scheduleClearPartitioningStateForDomains(const Vector<String>& domains);
101     void scheduleStatisticsAndDataRecordsProcessing();
102     void submitTelemetry();
103     void scheduleCookiePartitioningStateReset();
104
105     void scheduleClearInMemory();
106     
107     enum class ShouldGrandfather {
108         No,
109         Yes,
110     };
111     void scheduleClearInMemoryAndPersistent(ShouldGrandfather);
112     void scheduleClearInMemoryAndPersistent(std::chrono::system_clock::time_point modifiedSince, ShouldGrandfather);
113
114     void setTimeToLiveUserInteraction(Seconds);
115     void setTimeToLiveCookiePartitionFree(Seconds);
116     void setMinimumTimeBetweenDataRecordsRemoval(Seconds);
117     void setGrandfatheringTime(Seconds);
118     void setMaxStatisticsEntries(size_t);
119     void setPruneEntriesDownTo(size_t);
120     
121     void processStatistics(const WTF::Function<void (const WebCore::ResourceLoadStatistics&)>&) const;
122     void pruneStatisticsIfNeeded();
123
124     void resetParametersToDefaultValues();
125
126     std::unique_ptr<WebCore::KeyedEncoder> createEncoderFromData() const;
127     void mergeWithDataFromDecoder(WebCore::KeyedDecoder&);
128     void clearInMemory();
129     void grandfatherExistingWebsiteData();
130
131     void setStatisticsTestingCallback(Function<void (const String&)>&& callback) { m_statisticsTestingCallback = WTFMove(callback); }
132     void logTestingEvent(const String&);
133
134 private:
135     WebResourceLoadStatisticsStore(const String&, Function<void (const String&)>&& testingCallback, UpdatePrevalentDomainsWithAndWithoutInteractionHandler&&, RemovePrevalentDomainsHandler&&);
136
137     void removeDataRecords();
138
139     // IPC::MessageReceiver
140     void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
141
142     void performDailyTasks();
143     bool shouldRemoveDataRecords() const;
144     void setDataRecordsBeingRemoved(bool);
145
146     bool shouldPartitionCookies(const WebCore::ResourceLoadStatistics&) const;
147     bool hasStatisticsExpired(const WebCore::ResourceLoadStatistics&) const;
148     bool hasHadUnexpiredRecentUserInteraction(WebCore::ResourceLoadStatistics&) const;
149     void includeTodayAsOperatingDateIfNecessary();
150     Vector<String> topPrivatelyControlledDomainsToRemoveWebsiteDataFor();
151     void updateCookiePartitioning();
152     void updateCookiePartitioningForDomains(const Vector<String>& domainsToRemove, const Vector<String>& domainsToAdd, ShouldClearFirst);
153     void clearPartitioningStateForDomains(const Vector<String>& domains);
154     void mergeStatistics(Vector<WebCore::ResourceLoadStatistics>&&);
155     WebCore::ResourceLoadStatistics& ensureResourceStatisticsForPrimaryDomain(const String&);
156     void processStatisticsAndDataRecords();
157
158     void resetCookiePartitioningState();
159
160 #if PLATFORM(COCOA)
161     void registerUserDefaultsIfNeeded();
162 #endif
163
164     struct Parameters {
165         size_t pruneEntriesDownTo { 800 };
166         size_t maxStatisticsEntries { 1000 };
167         std::optional<Seconds> timeToLiveUserInteraction;
168         Seconds timeToLiveCookiePartitionFree { 24_h };
169         Seconds minimumTimeBetweenDataRecordsRemoval { 1_h };
170         Seconds grandfatheringTime { 24_h * 7 };
171         bool shouldNotifyPagesWhenDataRecordsWereScanned { false };
172         bool shouldClassifyResourcesBeforeDataRecordsRemoval { true };
173         bool shouldSubmitTelemetry { true };
174     };
175
176     HashMap<String, WebCore::ResourceLoadStatistics> m_resourceStatisticsMap;
177 #if HAVE(CORE_PREDICTION)
178     ResourceLoadStatisticsClassifierCocoa m_resourceLoadStatisticsClassifier;
179 #else
180     ResourceLoadStatisticsClassifier m_resourceLoadStatisticsClassifier;
181 #endif
182     Ref<WTF::WorkQueue> m_statisticsQueue;
183     ResourceLoadStatisticsPersistentStorage m_persistentStorage;
184     Vector<OperatingDate> m_operatingDates;
185
186     UpdatePrevalentDomainsWithAndWithoutInteractionHandler m_updatePrevalentDomainsWithAndWithoutInteractionHandler;
187     RemovePrevalentDomainsHandler m_removeDomainsHandler;
188
189     WallTime m_endOfGrandfatheringTimestamp;
190     RunLoop::Timer<WebResourceLoadStatisticsStore> m_dailyTasksTimer;
191     MonotonicTime m_lastTimeDataRecordsWereRemoved;
192
193     Parameters m_parameters;
194
195     bool m_dataRecordsBeingRemoved { false };
196
197     Function<void (const String&)> m_statisticsTestingCallback;
198 };
199
200 } // namespace WebKit