⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 101999 in webkit


Ignore:
Timestamp:
Dec 5, 2011, 7:38:11 AM (15 years ago)
Author:
eric.carlson@apple.com
Message:

Out-of-band text tracks may only load from same origin as the media element's Document's origin
https://bugs.webkit.org/show_bug.cgi?id=73184

Reviewed by Sam Weinig.

Source/WebCore:

Test: http/tests/security/text-track-crossorigin.html

  • html/HTMLTrackElement.cpp:

(WebCore::urlForLogging): Debug-only function for logging urls.
(WebCore::HTMLTrackElement::scheduleLoad): Call canLoadUrl() before passing control off to

the Track.

(WebCore::HTMLTrackElement::canLoadUrl): Don't ask HTMLMediaElement to validate the url, the

requirements for <track> are different from <video>.

(WebCore::HTMLTrackElement::didCompleteLoad): Change bool param to enum.
(WebCore::HTMLTrackElement::mediaElementCrossOriginAttribute): New, return parent 'crossorigin'

attribute value.

  • html/HTMLTrackElement.h:
  • html/LoadableTextTrack.cpp:

(WebCore::LoadableTextTrack::scheduleLoad): Add comments from the spec.
(WebCore::LoadableTextTrack::loadTimerFired): Always cancel pending loads. Let the caller know

if the loader refuses the url immediately.

(WebCore::LoadableTextTrack::cueLoadingStarted): The <track> deals with readyState.
(WebCore::LoadableTextTrack::cueLoadingCompleted): HTMLTrackElement::didCompleteLoad takes

an enum, not a bool.

  • loader/TextTrackLoader.cpp:

(WebCore::TextTrackLoader::corsPolicyPreventedLoad): New, log the error and set m_state.
(WebCore::TextTrackLoader::notifyFinished): Check for CORS failure.
(WebCore::TextTrackLoader::load): Take media element cross-origin attribute as a param so we

can make the correct checks.

  • loader/TextTrackLoader.h:

LayoutTests:

  • http/tests/security/resources/captions-with-access-control-headers.php: Added
  • http/tests/security/resources/captions.vtt: Added.
  • http/tests/security/text-track-crossorigin-expected.txt: Added.
  • http/tests/security/text-track-crossorigin.html: Added.
  • media/track/track-add-track-expected.txt: Updated results.
  • media/track/track-add-track.html: readyState changes as soon as the track url is set.
  • platform/efl/Skipped: Skip new test.
  • platform/gtk/Skipped: Ditto.
  • platform/mac/Skipped: Ditto.
  • platform/qt/Skipped: Ditto.
  • platform/win/Skipped: Ditto.
  • platform/wincairo/Skipped: Ditto.
Location:
trunk
Files:
4 added
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r101998 r101999  
     12011-12-05  Eric Carlson  <eric.carlson@apple.com>
     2
     3        Out-of-band text tracks may only load from same origin as the media element's Document's origin
     4        https://bugs.webkit.org/show_bug.cgi?id=73184
     5
     6        Reviewed by Sam Weinig.
     7
     8        * http/tests/security/resources/captions-with-access-control-headers.php: Added
     9        * http/tests/security/resources/captions.vtt: Added.
     10        * http/tests/security/text-track-crossorigin-expected.txt: Added.
     11        * http/tests/security/text-track-crossorigin.html: Added.
     12        * media/track/track-add-track-expected.txt: Updated results.
     13        * media/track/track-add-track.html: readyState changes as soon as the track url is set.
     14        * platform/efl/Skipped: Skip new test.
     15        * platform/gtk/Skipped: Ditto.
     16        * platform/mac/Skipped: Ditto.
     17        * platform/qt/Skipped: Ditto.
     18        * platform/win/Skipped: Ditto.
     19        * platform/wincairo/Skipped: Ditto.
     20
    1212011-12-05  Roland Steiner  <rolandsteiner@chromium.org>
    222
  • trunk/LayoutTests/media/track/track-add-track-expected.txt

    r101213 r101999  
    66RUN(trackElement.src = 'captions-webvtt/tc004-webvtt-file.vtt')
    77EXPECTED (video.textTracks.length == '1') OK
    8 EXPECTED (trackElement.readyState == '0') OK
     8EXPECTED (trackElement.readyState == '1') OK
    99EVENT(addtrack)
    1010EXPECTED (event.target == '[object TextTrackList]') OK
  • trunk/LayoutTests/media/track/track-add-track.html

    r101213 r101999  
    4343                run("trackElement.src = 'captions-webvtt/tc004-webvtt-file.vtt'");
    4444                testExpected("video.textTracks.length", 1);
    45                 testExpected("trackElement.readyState", HTMLTrackElement.NONE);
     45                testExpected("trackElement.readyState", HTMLTrackElement.LOADING);
    4646            }
    4747
  • trunk/LayoutTests/platform/efl/Skipped

    r101987 r101999  
    10991099# The EFL port has no support for <track> with *.vtt
    11001100media/track
     1101fast/events/constructors/track-event-constructor.html
     1102http/tests/security/text-track-crossorigin.html
    11011103
    11021104# The EFL port has no support for loading a PDF as an image
  • trunk/LayoutTests/platform/gtk/Skipped

    r101987 r101999  
    369369media/track
    370370fast/events/constructors/track-event-constructor.html
     371http/tests/security/text-track-crossorigin.html
    371372
    372373# CSS Filters is disabled
  • trunk/LayoutTests/platform/mac/Skipped

    r101987 r101999  
    448448media/track
    449449fast/events/constructors/track-event-constructor.html
     450http/tests/security/text-track-crossorigin.html
    450451
    451452# Tests for MediaSource API. Feature is not yet functional.
  • trunk/LayoutTests/platform/qt/Skipped

    r101987 r101999  
    24442444# track not functional yet.
    24452445fast/events/constructors/track-event-constructor.html
     2446http/tests/security/text-track-crossorigin.html
    24462447
    24472448# Skip because this platform does not support a paging mouse wheel event
  • trunk/LayoutTests/platform/win/Skipped

    r101987 r101999  
    14281428media/track
    14291429fast/events/constructors/track-event-constructor.html
     1430http/tests/security/text-track-crossorigin.html
    14301431
    14311432# Tests for MediaSource API. Feature is not yet functional.
  • trunk/LayoutTests/platform/wincairo/Skipped

    r101987 r101999  
    19391939media/track
    19401940fast/events/constructors/track-event-constructor.html
     1941http/tests/security/text-track-crossorigin.html
    19411942
    19421943# Tests for MediaSource API. Feature is not yet functional.
  • trunk/Source/WebCore/ChangeLog

    r101998 r101999  
     12011-12-05  Eric Carlson  <eric.carlson@apple.com>
     2
     3        Out-of-band text tracks may only load from same origin as the media element's Document's origin
     4        https://bugs.webkit.org/show_bug.cgi?id=73184
     5
     6        Reviewed by Sam Weinig.
     7
     8        Test: http/tests/security/text-track-crossorigin.html
     9
     10        * html/HTMLTrackElement.cpp:
     11        (WebCore::urlForLogging): Debug-only function for logging urls.
     12        (WebCore::HTMLTrackElement::scheduleLoad): Call canLoadUrl() before passing control off to
     13            the Track.
     14        (WebCore::HTMLTrackElement::canLoadUrl): Don't ask HTMLMediaElement to validate the url, the
     15            requirements for <track> are different from <video>.
     16        (WebCore::HTMLTrackElement::didCompleteLoad): Change bool param to enum.
     17        (WebCore::HTMLTrackElement::mediaElementCrossOriginAttribute): New, return parent 'crossorigin'
     18            attribute value.
     19        * html/HTMLTrackElement.h:
     20
     21        * html/LoadableTextTrack.cpp:
     22        (WebCore::LoadableTextTrack::scheduleLoad): Add comments from the spec.
     23        (WebCore::LoadableTextTrack::loadTimerFired): Always cancel pending loads. Let the caller know
     24            if the loader refuses the url immediately.
     25        (WebCore::LoadableTextTrack::cueLoadingStarted): The <track> deals with readyState.
     26        (WebCore::LoadableTextTrack::cueLoadingCompleted): HTMLTrackElement::didCompleteLoad takes
     27            an enum, not a bool.
     28
     29        * loader/TextTrackLoader.cpp:
     30        (WebCore::TextTrackLoader::corsPolicyPreventedLoad): New, log the error and set m_state.
     31        (WebCore::TextTrackLoader::notifyFinished): Check for CORS failure.
     32        (WebCore::TextTrackLoader::load): Take media element cross-origin attribute as a param so we
     33            can make the correct checks.
     34        * loader/TextTrackLoader.h:
     35
    1362011-12-05  Roland Steiner  <rolandsteiner@chromium.org>
    237
  • trunk/Source/WebCore/html/HTMLTrackElement.cpp

    r101673 r101999  
    2929#include "HTMLTrackElement.h"
    3030
     31#include "ContentSecurityPolicy.h"
    3132#include "Event.h"
    3233#include "HTMLMediaElement.h"
     
    4243using namespace HTMLNames;
    4344
     45#if !LOG_DISABLED
     46static String urlForLogging(const KURL& url)
     47{
     48    static const unsigned maximumURLLengthForLogging = 128;
     49   
     50    if (url.string().length() < maximumURLLengthForLogging)
     51        return url.string();
     52    return url.string().substring(0, maximumURLLengthForLogging) + "...";
     53}
     54#endif
     55   
    4456inline HTMLTrackElement::HTMLTrackElement(const QualifiedName& tagName, Document* document)
    4557    : HTMLElement(tagName, document)
     
    193205        return;
    194206
    195     ensureTrack()->scheduleLoad(getNonEmptyURLAttribute(srcAttr));
    196 }
    197 
    198 bool HTMLTrackElement::canLoadUrl(LoadableTextTrack*, const KURL& url)
     207    // 4.8.10.12.3 Sourcing out-of-band text tracks
     208
     209    // 1. Set the text track readiness state to loading.
     210    setReadyState(HTMLTrackElement::LOADING);
     211
     212    KURL url = getNonEmptyURLAttribute(srcAttr);
     213    if (!canLoadUrl(url)) {
     214        didCompleteLoad(ensureTrack(), HTMLTrackElement::Failure);
     215        return;
     216    }
     217
     218    ensureTrack()->scheduleLoad(url);
     219}
     220
     221bool HTMLTrackElement::canLoadUrl(const KURL& url)
    199222{
    200223    if (!RuntimeEnabledFeatures::webkitVideoTrackEnabled())
     
    205228        return false;
    206229
    207     if (!parent->isSafeToLoadURL(url, HTMLMediaElement::Complain))
     230    // 4.8.10.12.3 Sourcing out-of-band text tracks
     231
     232    // 4. Download: If URL is not the empty string, perform a potentially CORS-enabled fetch of URL, with the
     233    // mode being the state of the media element's crossorigin content attribute, the origin being the
     234    // origin of the media element's Document, and the default origin behaviour set to fail.
     235    if (url.isEmpty())
    208236        return false;
     237
     238    if (!document()->contentSecurityPolicy()->allowMediaFromSource(url)) {
     239        DEFINE_STATIC_LOCAL(String, consoleMessage, ("Text track load denied by Content Security Policy."));
     240        document()->addConsoleMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage);
     241        LOG(Media, "HTMLTrackElement::canLoadUrl(%s) -> rejected by Content Security Policy", urlForLogging(url).utf8().data());
     242        return false;
     243    }
    209244   
    210245    return dispatchBeforeLoadEvent(url.string());
    211246}
    212247
    213 void HTMLTrackElement::didCompleteLoad(LoadableTextTrack*, bool loadingFailed)
    214 {
    215     loadingFailed ? setReadyState(HTMLTrackElement::TRACK_ERROR) : setReadyState(HTMLTrackElement::LOADED);
    216 
     248void HTMLTrackElement::didCompleteLoad(LoadableTextTrack*, LoadStatus status)
     249{
    217250    ExceptionCode ec = 0;
    218     dispatchEvent(Event::create(loadingFailed ? eventNames().errorEvent : eventNames().loadEvent, false, false), ec);
     251
     252    // 4.8.10.12.3 Sourcing out-of-band text tracks (continued)
     253   
     254    // 4. Download: ...
     255    // If the fetching algorithm fails for any reason (network error, the server returns an error
     256    // code, a cross-origin check fails, etc), or if URL is the empty string or has the wrong origin
     257    // as determined by the condition at the start of this step, or if the fetched resource is not in
     258    // a supported format, then queue a task to first change the text track readiness state to failed
     259    // to load and then fire a simple event named error at the track element; and then, once that task
     260    // is queued, move on to the step below labeled monitoring.
     261
     262    if (status == Failure) {
     263        setReadyState(HTMLTrackElement::TRACK_ERROR);
     264        dispatchEvent(Event::create(eventNames().errorEvent, false, false), ec);
     265        return;
     266    }
     267
     268    // If the fetching algorithm does not fail, then the final task that is queued by the networking
     269    // task source must run the following steps:
     270    //     1. Change the text track readiness state to loaded.
     271    setReadyState(HTMLTrackElement::LOADED);
     272
     273    //     2. If the file was successfully processed, fire a simple event named load at the
     274    //        track element.
     275    dispatchEvent(Event::create(eventNames().loadEvent, false, false), ec);
    219276}
    220277
     
    236293    return static_cast<ReadyState>(ensureTrack()->readinessState());
    237294}
    238    
     295
     296const AtomicString& HTMLTrackElement::mediaElementCrossOriginAttribute() const
     297{
     298    if (HTMLMediaElement* parent = mediaElement())
     299        return parent->fastGetAttribute(HTMLNames::crossoriginAttr);
     300   
     301    return nullAtom;
     302}
     303
    239304void HTMLTrackElement::textTrackKindChanged(TextTrack* track)
    240305{
  • trunk/Source/WebCore/html/HTMLTrackElement.h

    r101673 r101999  
    6161
    6262    TextTrack* track();
    63    
     63
    6464    void scheduleLoad();
    65     virtual bool canLoadUrl(LoadableTextTrack*, const KURL&);
    66     virtual void didCompleteLoad(LoadableTextTrack*, bool /* loadingFailed */);
    67    
     65
     66    enum LoadStatus { Failure, Success };
     67    virtual void didCompleteLoad(LoadableTextTrack*, LoadStatus);
     68
     69    const AtomicString& mediaElementCrossOriginAttribute() const;
     70
    6871private:
    6972    HTMLTrackElement(const QualifiedName&, Document*);
     
    9396
    9497    LoadableTextTrack* ensureTrack();
     98    virtual bool canLoadUrl(const KURL&);
    9599
    96100    RefPtr<LoadableTextTrack> m_track;
  • trunk/Source/WebCore/html/LoadableTextTrack.cpp

    r101213 r101999  
    5858void LoadableTextTrack::scheduleLoad(const KURL& url)
    5959{
     60    if (url == m_url)
     61        return;
     62
     63    // 4.8.10.12.3 Sourcing out-of-band text tracks (continued)
     64
     65    // 2. Let URL be the track URL of the track element.
    6066    m_url = url;
     67   
     68    // 3. Asynchronously run the remaining steps, while continuing with whatever task
     69    // was responsible for creating the text track or changing the text track mode.
    6170    if (!m_loadTimer.isActive())
    6271        m_loadTimer.startOneShot(0);
     
    6574void LoadableTextTrack::loadTimerFired(Timer<LoadableTextTrack>*)
    6675{
     76    if (m_loader)
     77        m_loader->cancelLoad();
     78
    6779    if (!m_trackElement)
    6880        return;
    6981
    70     m_trackElement->setReadyState(HTMLTrackElement::LOADING);
    71    
    72     if (m_loader)
    73         m_loader->cancelLoad();
     82    // 4.8.10.12.3 Sourcing out-of-band text tracks (continued)
    7483
    75     if (!m_trackElement->canLoadUrl(this, m_url)) {
    76         m_trackElement->setReadyState(HTMLTrackElement::TRACK_ERROR);
    77         return;
    78     }
    79 
     84    // 4. Download: If URL is not the empty string, perform a potentially CORS-enabled fetch of URL, with the
     85    // mode being the state of the media element's crossorigin content attribute, the origin being the
     86    // origin of the media element's Document, and the default origin behaviour set to fail.
    8087    m_loader = TextTrackLoader::create(this, static_cast<ScriptExecutionContext*>(m_trackElement->document()));
    81     m_loader->load(m_url);
     88    if (!m_loader->load(m_url, m_trackElement->mediaElementCrossOriginAttribute()))
     89        m_trackElement->didCompleteLoad(this, HTMLTrackElement::Failure);
    8290}
    8391
     
    104112{
    105113    ASSERT_UNUSED(loader, m_loader == loader);
    106    
    107     if (!m_trackElement)
    108         return;
    109     m_trackElement->setReadyState(HTMLTrackElement::LOADING);
    110114}
    111115
     
    116120    if (!m_trackElement)
    117121        return;
    118     m_trackElement->didCompleteLoad(this, loadingFailed);
     122
     123    m_trackElement->didCompleteLoad(this, loadingFailed ? HTMLTrackElement::Failure : HTMLTrackElement::Success);
    119124}
    120125
  • trunk/Source/WebCore/loader/TextTrackLoader.cpp

    r101185 r101999  
    3232#include "CachedResourceLoader.h"
    3333#include "CachedTextTrack.h"
     34#include "CrossOriginAccessControl.h"
    3435#include "Document.h"
    3536#include "Logging.h"
    3637#include "ResourceHandle.h"
     38#include "SecurityOrigin.h"
    3739#include "SharedBuffer.h"
    3840#include "WebVTTParser.h"
     
    140142}
    141143
     144void TextTrackLoader::corsPolicyPreventedLoad()
     145{
     146    DEFINE_STATIC_LOCAL(String, consoleMessage, ("Cross-origin text track load denied by Cross-Origin Resource Sharing policy."));
     147    Document* document = static_cast<Document*>(m_scriptExecutionContext);
     148    document->addConsoleMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage);
     149    m_state = Failed;
     150}
     151
    142152void TextTrackLoader::notifyFinished(CachedResource* resource)
    143153{
    144154    ASSERT(m_cachedCueData == resource);
    145155
    146     processNewCueData(resource);
    147 
    148     if (m_state != Failed)
    149         m_state = resource->errorOccurred() ? Failed : Finished;
     156    Document* document = static_cast<Document*>(m_scriptExecutionContext);
     157    if (!m_crossOriginMode.isNull()
     158        && !document->securityOrigin()->canRequest(resource->response().url())
     159        && !resource->passesAccessControlCheck(document->securityOrigin())) {
     160
     161        corsPolicyPreventedLoad();
     162    }
     163
     164    if (m_state != Failed) {
     165        processNewCueData(resource);
     166        if (m_state != Failed)
     167            m_state = resource->errorOccurred() ? Failed : Finished;
     168    }
    150169
    151170    if (!m_cueLoadTimer.isActive())
     
    155174}
    156175
    157 bool TextTrackLoader::load(const KURL& url)
    158 {
     176bool TextTrackLoader::load(const KURL& url, const String& crossOriginMode)
     177{
     178    cancelLoad();
     179
    159180    if (!m_client->shouldLoadCues(this))
    160181        return false;
    161    
    162     cancelLoad();
    163    
     182
    164183    ASSERT(m_scriptExecutionContext->isDocument());
    165184    Document* document = static_cast<Document*>(m_scriptExecutionContext);
    166    
    167185    ResourceRequest cueRequest(document->completeURL(url));
     186
     187    if (!crossOriginMode.isNull()) {
     188        m_crossOriginMode = crossOriginMode;
     189        StoredCredentials allowCredentials = equalIgnoringCase(crossOriginMode, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials;
     190        updateRequestForAccessControl(cueRequest, document->securityOrigin(), allowCredentials);
     191    } else {
     192        // Cross-origin resources that are not suitably CORS-enabled may not load.
     193        if (!document->securityOrigin()->canRequest(url)) {
     194            corsPolicyPreventedLoad();
     195            return false;
     196        }
     197    }
     198
    168199    CachedResourceLoader* cachedResourceLoader = document->cachedResourceLoader();
    169200    m_cachedCueData = static_cast<CachedTextTrack*>(cachedResourceLoader->requestTextTrack(cueRequest));
  • trunk/Source/WebCore/loader/TextTrackLoader.h

    r99984 r101999  
    6262    virtual ~TextTrackLoader();
    6363   
    64     bool load(const KURL&);
     64    bool load(const KURL&, const String& crossOriginMode);
    6565    void cancelLoad();
    6666    void getNewCues(Vector<RefPtr<TextTrackCue> >& outputCues);
     
    7979    void processNewCueData(CachedResource*);
    8080    void cueLoadTimerFired(Timer<TextTrackLoader>*);
     81    void corsPolicyPreventedLoad();
    8182
    8283    enum State { Idle, Loading, Finished, Failed };
     
    8788    ScriptExecutionContext* m_scriptExecutionContext;
    8889    Timer<TextTrackLoader> m_cueLoadTimer;
     90    String m_crossOriginMode;
    8991    State m_state;
    9092    unsigned m_parseOffset;
Note: See TracChangeset for help on using the changeset viewer.