summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Klocek <michal.klocek@qt.io>2018-08-10 12:22:39 +0200
committerMichal Klocek <michal.klocek@qt.io>2018-08-10 14:46:08 +0000
commite8b9ae61d0fc8123da8170dc8b4bdc561dcb7e32 (patch)
treeae677e6516800a92238035723c0d7437a4d0c699
parent0cce345ee0781cda8effabf7521b9a3653c6674e (diff)
[Backport] CVE-2018-6177 CVE-2018-6168
defeat cors attacks on audio/video tags Neutralize error messages and fire no progress events until media metadata has been loaded for media loaded from cross-origin locations. Bug: 828265, 826187 Reviewed-on: https://chromium-review.googlesource.com/1015794 Change-Id: Ie8064f04c606f11bfa88a72b1d5ef82a84bdd409 Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
-rw-r--r--chromium/third_party/WebKit/Source/core/html/media/HTMLMediaElement.cpp40
-rw-r--r--chromium/third_party/WebKit/Source/core/html/media/HTMLMediaElement.h10
2 files changed, 40 insertions, 10 deletions
diff --git a/chromium/third_party/WebKit/Source/core/html/media/HTMLMediaElement.cpp b/chromium/third_party/WebKit/Source/core/html/media/HTMLMediaElement.cpp
index c05d0a33521..1d92423de4b 100644
--- a/chromium/third_party/WebKit/Source/core/html/media/HTMLMediaElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/media/HTMLMediaElement.cpp
@@ -1528,14 +1528,17 @@ void HTMLMediaElement::WaitForSourceChange() {
GetLayoutObject()->UpdateFromElement();
}
-void HTMLMediaElement::NoneSupported(const String& message) {
- BLINK_MEDIA_LOG << "NoneSupported(" << (void*)this << ", message='" << message
+void HTMLMediaElement::NoneSupported(const String& input_message) {
+ BLINK_MEDIA_LOG << "NoneSupported(" << (void*)this << ", message='" << input_message
<< "')";
StopPeriodicTimers();
load_state_ = kWaitingForSource;
current_source_node_ = nullptr;
+ String empty_string;
+ const String& message = MediaShouldBeOpaque() ? empty_string : input_message;
+
// 4.8.12.5
// The dedicated media source failure steps are the following steps:
@@ -1611,11 +1614,17 @@ void HTMLMediaElement::NetworkStateChanged() {
}
void HTMLMediaElement::MediaLoadingFailed(WebMediaPlayer::NetworkState error,
- const String& message) {
+ const String& input_message) {
BLINK_MEDIA_LOG << "MediaLoadingFailed(" << (void*)this << ", "
- << static_cast<int>(error) << ", message='" << message
+ << static_cast<int>(error) << ", message='" << input_message
<< "')";
+ bool should_be_opaque = MediaShouldBeOpaque();
+ if (should_be_opaque)
+ error = WebMediaPlayer::kNetworkStateNetworkError;
+ String empty_string;
+ const String& message = should_be_opaque ? empty_string : input_message;
+
StopPeriodicTimers();
// If we failed while trying to load a <source> element, the movie was never
@@ -1718,12 +1727,14 @@ void HTMLMediaElement::SetNetworkState(WebMediaPlayer::NetworkState state) {
void HTMLMediaElement::ChangeNetworkStateFromLoadingToIdle() {
progress_event_timer_.Stop();
+ if (!MediaShouldBeOpaque()) {
// Schedule one last progress event so we guarantee that at least one is fired
// for files that load very quickly.
- if (GetWebMediaPlayer() && GetWebMediaPlayer()->DidLoadingProgress())
- ScheduleEvent(EventTypeNames::progress);
- ScheduleEvent(EventTypeNames::suspend);
- SetNetworkState(kNetworkIdle);
+ if (GetWebMediaPlayer() && GetWebMediaPlayer()->DidLoadingProgress())
+ ScheduleEvent(EventTypeNames::progress);
+ ScheduleEvent(EventTypeNames::suspend);
+ SetNetworkState(kNetworkIdle);
+ }
}
void HTMLMediaElement::ReadyStateChanged() {
@@ -1891,6 +1902,14 @@ void HTMLMediaElement::ProgressEventTimerFired(TimerBase*) {
if (network_state_ != kNetworkLoading)
return;
+ // If this is an cross-origin request, and we haven't discovered whether
+ // the media is actually playable yet, don't fire any progress events as
+ // those may let the page know information about the resource that it's
+ // not supposed to know.
+
+ if (MediaShouldBeOpaque())
+ return;
+
double time = WTF::CurrentTime();
double timedelta = time - previous_progress_time_;
@@ -4206,6 +4225,11 @@ gfx::ColorSpace HTMLMediaElement::TargetColorSpace() {
return frame->GetPage()->GetChromeClient().GetScreenInfo().color_space;
}
+bool HTMLMediaElement::MediaShouldBeOpaque() const {
+ return !IsMediaDataCORSSameOrigin(GetDocument().GetSecurityOrigin()) &&
+ ready_state_ < kHaveMetadata && !FastGetAttribute(srcAttr).IsEmpty();
+}
+
void HTMLMediaElement::CheckViewportIntersectionTimerFired(TimerBase*) {
bool should_report_root_bounds = true;
IntersectionGeometry geometry(nullptr, *this, Vector<Length>(),
diff --git a/chromium/third_party/WebKit/Source/core/html/media/HTMLMediaElement.h b/chromium/third_party/WebKit/Source/core/html/media/HTMLMediaElement.h
index 3ce50fb760b..c39178808b6 100644
--- a/chromium/third_party/WebKit/Source/core/html/media/HTMLMediaElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/media/HTMLMediaElement.h
@@ -258,8 +258,8 @@ class CORE_EXPORT HTMLMediaElement
using HTMLElement::GetExecutionContext;
bool HasSingleSecurityOrigin() const {
- return GetWebMediaPlayer() &&
- GetWebMediaPlayer()->HasSingleSecurityOrigin();
+ return GetWebMediaPlayer() ? GetWebMediaPlayer()->HasSingleSecurityOrigin()
+ : true;
}
bool IsFullscreen() const;
@@ -342,6 +342,12 @@ class CORE_EXPORT HTMLMediaElement
InsertionNotificationRequest InsertedInto(ContainerNode*) override;
void RemovedFrom(ContainerNode*) override;
+ // Return true if media is cross origin from the current document
+ // and has not passed a cors check, meaning that we should return
+ // as little information as possible about it.
+
+ bool MediaShouldBeOpaque() const;
+
void DidMoveToNewDocument(Document& old_document) override;
virtual KURL PosterImageURL() const { return KURL(); }