Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Limit DOMAudioSession to third-party iframes having microphone access
https://bugs.webkit.org/show_bug.cgi?id=249577
rdar://problem/103514560

Reviewed by Eric Carlson.

We might want to allow access to DOMAudioSession to more third party iframes in the future.
For now, since the main use case is microphone/WebRTC related, let's reduce access to those iframes that can access microphones.

* LayoutTests/http/tests/webrtc/audioSessionInFrames-expected.txt: Added.
* LayoutTests/http/tests/webrtc/audioSessionInFrames.html: Added.
* LayoutTests/http/tests/webrtc/resources/audioSessionFrame.html: Added.
* LayoutTests/platform/glib/TestExpectations:
* Source/WTF/Scripts/Preferences/WebPreferencesExperimental.yaml:
* Source/WebCore/Modules/audiosession/DOMAudioSession.cpp:
(WebCore::DOMAudioSession::setType):
(WebCore::DOMAudioSession::type const):
(WebCore::DOMAudioSession::state const):
(WebCore::DOMAudioSession::scheduleStateChangeEvent):

Canonical link: https://commits.webkit.org/258423@main
  • Loading branch information
youennf committed Jan 4, 2023
1 parent 95574fc commit 841d41b
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 0 deletions.
@@ -0,0 +1,3 @@

PASS Allow audioSession in iframes where microphone is allowed

35 changes: 35 additions & 0 deletions LayoutTests/http/tests/webrtc/audioSessionInFrames.html
@@ -0,0 +1,35 @@
<!DOCTYPE html>
<body>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
function with_iframe(url, allow) {
let frame = document.createElement('iframe');
frame.src = url;
frame.setAttribute('allow', allow);
return new Promise(resolve => {
frame.onload = () => { resolve(frame); };
document.body.appendChild(frame);
});
}

promise_test(async () => {
navigator.audioSession.type = "play-and-record";
await navigator.mediaDevices.getUserMedia({ audio: true });

const frame1 = await with_iframe("http://localhost:8080/webrtc/resources/audioSessionFrame.html", "microphone:'none'");
const result1 = await new Promise(resolve => window.onmessage = (event) => resolve(event.data));
frame1.remove();

const frame2 = await with_iframe("http://localhost:8080/webrtc/resources/audioSessionFrame.html", "microphone");
const result2 = await new Promise(resolve => window.onmessage = (event) => resolve(event.data));
frame2.remove();

assert_equals(result1.type, "auto");
assert_equals(result1.state, "inactive");

assert_equals(result2.type, "play-and-record");
assert_equals(result2.state, "active");
}, "Allow audioSession in iframes where microphone is allowed");
</script>
</body>
11 changes: 11 additions & 0 deletions LayoutTests/http/tests/webrtc/resources/audioSessionFrame.html
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<body>
<script>
onload = () => {
parent.postMessage({
type: navigator.audioSession.type,
state: navigator.audioSession.state
}, "*");
}
</script>
</body>
1 change: 1 addition & 0 deletions LayoutTests/platform/glib/TestExpectations
Expand Up @@ -1232,6 +1232,7 @@ webkit.org/b/233796 imported/w3c/web-platform-tests/html/browsers/browsing-the-w
#////////////////////////////////////////////////////////////////////////////////////////

media/audioSession [ Skip ]
http/tests/webrtc/audioSessionInFrames.html [ Skip ]

#////////////////////////////////////////////////////////////////////////////////////////
# End of Media-related bugs
Expand Down
15 changes: 15 additions & 0 deletions Source/WebCore/Modules/audiosession/DOMAudioSession.cpp
Expand Up @@ -31,6 +31,7 @@
#include "AudioSession.h"
#include "Document.h"
#include "EventNames.h"
#include "FeaturePolicy.h"
#include "PlatformMediaSessionManager.h"

namespace WebCore {
Expand Down Expand Up @@ -83,6 +84,9 @@ ExceptionOr<void> DOMAudioSession::setType(Type type)
if (!document)
return Exception { InvalidStateError };

if (!isFeaturePolicyAllowedByDocumentAndAllOwners(FeaturePolicy::Type::Microphone, *document, LogFeaturePolicyFailure::No))
return { };

document->topDocument().setAudioSessionType(type);

auto categoryOverride = fromDOMAudioSessionType(type);
Expand All @@ -97,6 +101,9 @@ ExceptionOr<void> DOMAudioSession::setType(Type type)
DOMAudioSession::Type DOMAudioSession::type() const
{
auto* document = downcast<Document>(scriptExecutionContext());
if (document && !isFeaturePolicyAllowedByDocumentAndAllOwners(FeaturePolicy::Type::Microphone, *document, LogFeaturePolicyFailure::No))
return DOMAudioSession::Type::Auto;

return document ? document->topDocument().audioSessionType() : DOMAudioSession::Type::Auto;
}

Expand All @@ -113,6 +120,10 @@ static DOMAudioSession::State computeAudioSessionState()

DOMAudioSession::State DOMAudioSession::state() const
{
auto* document = downcast<Document>(scriptExecutionContext());
if (!document || !isFeaturePolicyAllowedByDocumentAndAllOwners(FeaturePolicy::Type::Microphone, *document, LogFeaturePolicyFailure::No))
return DOMAudioSession::State::Inactive;

if (!m_state)
m_state = computeAudioSessionState();
return *m_state;
Expand Down Expand Up @@ -149,6 +160,10 @@ void DOMAudioSession::activeStateChanged()

void DOMAudioSession::scheduleStateChangeEvent()
{
auto* document = downcast<Document>(scriptExecutionContext());
if (document && !isFeaturePolicyAllowedByDocumentAndAllOwners(FeaturePolicy::Type::Microphone, *document, LogFeaturePolicyFailure::No))
return;

if (m_hasScheduleStateChangeEvent)
return;

Expand Down

0 comments on commit 841d41b

Please sign in to comment.