Skip to content
This repository has been archived by the owner on Dec 11, 2019. It is now read-only.

YouTube - Player Update - Authenticated users seeing ads #7230

Closed
lukemulks opened this issue Feb 14, 2017 · 5 comments
Closed

YouTube - Player Update - Authenticated users seeing ads #7230

lukemulks opened this issue Feb 14, 2017 · 5 comments
Assignees
Labels
feature/adblock help wanted The PR/issue opener needs help to complete/report the task. site-bug

Comments

@lukemulks
Copy link
Collaborator

lukemulks commented Feb 14, 2017

  • Did you search for similar issues before submitting this one?
    Yes

  • Describe the issue you encountered:
    Youtube updated their player on 02.10.2017, working in some additional ad blocking flags and countermeasures that had been resolved w/Brave v0.13.0.

After the update on 02.10.17, unauthenticated users are still able to block ads, but authenticated users are seeing ads serve with shields up.

Embedded iframe youtube players on non-yt domains are also failing to play with shields up. Once shields are down, the embedded content plays.

  • Platform (Win7, 8, 10? macOS? Linux distro?):
    MacOS, Win10, Linux

  • Brave Version (revision SHA):
    v0.13.2

  • Steps to reproduce:

    1. Go to youtube.com
    2. Sign into Google acct
    3. ,See ads.
  • Actual result:
    Ads

  • Expected result:
    No ads (match behavior for unauthenticated users)

  • Will the steps above reproduce in a fresh profile? If not what other info can be added?
    Yes.

  • Is this an issue in the currently released version?
    Yes.

  • Can this issue be consistently reproduced?
    Yes

  • Breakout of investigation so far:

QUIC disabled in v0.13.0

  • Majority of users no longer see ads.
  • Some users report ads, but issue is resolved once Goolge Ads Settings (for their Google profile) are switched OFF for relevant and search ads)

02.10.2017

  • YT updates player, includes new experiments and html5 prerender options.
  • YT updates dev policy to mention ad blocking .
  • 3 users report issue while authenticated. Repro'd from Brave.

The Problem: Many of the pieces involved overlap between content and ads. I'm going to lay out the investigation below, along with some additional areas we could test further.

Client side blocking doesn't appear to work so well from traditional blacklisting methods.
Recommending that we try blocking VAST and VMAP, which are specific to ads, and shouldn't impact content.

The challenge with VAST/VMAP blocking is that this is typically done in pure XML, but appears to be encoded to work with the gRPC config.

Rewrites, etc. might work well as an alternative

============================================
Notes from the previous investigation: 02.10-02.13.17

gRPC (observed when QUIC is disabled)
It was discovered that Google is using gRPC for RPC method bundling for Google APIs (location, ads, books, maps, social).

Each of these JS requests contain a differentgapi_loaded=[VALUE]for a different set of Google APIs

cb=gapi.loaded_0:

  • Forms the gRPC calls,
  • Establishes OAUTH flow
  • Includes user Social (g+) and other user-ID related APIs
  • (core user and structural request)

Full Request:
https://apis.google.com/_/scs/abc-static/_/js/k=gapi.gapi.en.ht56ryQzVZ8.O/m=googleapis_proxy/rt=j/sv=1/d=1/ed=1/rs=AHpOoo9BOneF1L6M_FnbxCRKqYNTbnMzBg/cb=gapi.loaded_0

   rpc: "/rpc",
            root: "https://content.googleapis.com",
            "root-1p": "https://clients6.google.com",
            sessionCache: {
                enabled: !0
            },
            transport: {
                isProxyShared: !0
            },
            xd3: "/static/proxy.html",
            developerKey: "AIzaSyCKSbrvQasunBoV16zDH9R33D88CeLr9gQ",
            auth: {
                useInterimAuth: !1
            }

cb=gapi.loaded_2:

  • This includes the IMA for video ads
  • This includes the annotations module for metadata and other playback params.
  • This is critical in serving ads. Includes a lot of other widgets and user data used for ads.

Full Request:
https://apis.google.com/_/scs/abc-static/_/js/k=gapi.gapi.en.ht56ryQzVZ8.O/m=client/exm=card,gapi_iframes,gapi_iframes_style_slide_menu/rt=j/sv=1/d=1/ed=1/rs=AHpOoo9BOneF1L6M_FnbxCRKqYNTbnMzBg/cb=gapi.loaded_2

The IMA code from the response:

    ":ima": {
            "versions": {
                ":3": "1",
                ":3.0": "1"
            },
            "path": "/api/ima/3.0/28a914332232c9a8ac0ae8da68b1006e/",
            "js": "default.I.js",
            "properties": {
                ":Version": "3.0",
                ":JSHash": "28a914332232c9a8ac0ae8da68b1006e"
            }
        }

Annotations are used for XML nodes and tracking. Code from response.

    ":annotations": {
            "versions": {
                ":1": "1",
                ":1.0": "1"
            },
            "path": "/api/annotations/1.0/3b0f18d6e7bf8cf053640179ef6d98d1/",
            "js": "default+en.I.js",
            "properties": {
                ":Version": "1.0",
                ":JSHash": "3b0f18d6e7bf8cf053640179ef6d98d1"
            }
        },

OAuth postMessage relay
Google is also using OAuth postMessage relay calls w/gRPC that are packaging ad request data
Request URL:
https://accounts.google.com/o/oauth2/postmessageRelay?parent=https%3A%2F%2Fwww.youtube.com&jsh=m%3B%2F_%2Fscs%2Fabc-static%2F_%2Fjs%2Fk%3Dgapi.gapi.en.ht56ryQzVZ8.O%2Fm%3D__features__%2Frt%3Dj%2Fd%3D1%2Frs%3DAHpOoo9BOneF1L6M_FnbxCRKqYNTbnMzBg

Client Side Network Traffic

The VMAP and VAST Ad Manifest framework preloads w/this request:
https://www.youtube.com/watch?v=r0n-ED3Oxr0&t=2s&spf=navigate
"vmap": "\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\u003cvmap**:VMAP** xmlns:vmap=\"http:\/\/www.iab.net\/videosuite\/vmap\" xmlns:yt=\"http:\/\/youtube.com\" version=\"1.0\"\u003e\u003cvmap:AdBreak breakType=\"linear\" timeOffset=\"start\"\u003e\u003cvmap:AdSource allowMultipleAds = \"false\"\u003e\u003cvmap:VASTData\u003e\u003**cVAST** version=\"3.0\"\u003e\u003cAd\u003e\u003cWrapper\u003e\u003cAdSystem version=\"1\"\u003eYT:DoubleClick\u003c\/AdSystem\u003e\u003c**VASTAdTagURI\**u003e\u003c!

VASTAdTagURI= the XML node that contains the URI to the video ad.

These all appear to be encoded for the gRPC configuration. Traditionally they'd be in XML.

Google's JS API autoload call for their ad module.
This request includes an ad module flag within the query string parameters (Google uses his same call for other modules):
Request URL:
https://www.google.com/jsapi?autoload=%7B%22modules%22%3A%5B%7B%22name%22%3A%22ads%22%2C%22version%22%3A%221%22%2C%22callback%22%3A%22(function()%7B%7D)%22%2C%22packages%22%3A%5B%22content%22%5D%7D%5D%7D

Decoded Query String Parameter values:
autoload:{"modules":[{"name":"ads","version":"1","callback":"(function(){})","packages":["content"]}]}

This is used to write and load the IMA into an iframe: :https://www.google.com/uds/api/ads/1.0/4088387d0f85fb494bbd48b881b424a7/content.I.js

This is used for what would typically be XML Tracking Extension nodes:
https://www.youtube.com/annotations_invideo?instream_ad=*

This is used for the instream ad stats api:
https://www.youtube.com/api/stats/ads?*

Blacklisting/Client Side Blocking Tests:
I tried blocking each of the above using blacklisting and URL block rules, and didn't get anywhere. I think this is due to the calls being formed via gRPC, which is using XHR with fallbacks when errors are thrown by blocking.

Player Resources (for rewirting, etc).
I dug deeper into the resources for the player and ads (Dev Tools / Sources) so I could catch the failovers and other ad stuff within each of the client side resources.

The screencap below is marked up to include points of reference for the YT Ads and Player config (taken when an ad was playing).

brave-yt-devtools-yt-ad-resources-02132017

The heart of the client-side ad config is within the following resource files:

top / www.youtube.com / yts / jsbin/...

  • ...player-enUS-vfl8LqiZp/remote.js
    (contains cast_sender.js extension calls for proxy requests)

  • ...player-enUS-vfl8LqiZp/annotations_module.js
    (contains VAST references)

  • ...player-enUS-vfl8LqiZp/base.js
    (VAST references)

  • ...www-en_US-vflzPvQ1b/base.js
    (ad configuration)

  • ...www-en_US-vflzPvQ1b/watch.js
    (majority of ad references, including ad blocking references)

  • ...www-en_US-vflzPvQ1b/common.js
    (several ad references)

  • ...www-en_US-vflzPvQ1b/watch_autoplayrenderer.js
    (no direct ad references, but prefetch references)

  • ...www-en_US-vflzPvQ1b/watch_speedyg.js
    (invokes the spdy player config)

  • ...www-en_US-vflzPvQ1b/watch_transcript.js
    (appears to be where the VAST XML is parsed)

I need assistance with:
-Figuring out the best method of attack.
-Implementing it in a frictionless way.
-Testing in MacOS
-I'm down and available to test in Windows.

@luixxiul
Copy link
Contributor

I removed labels for OS as the issue affects all of the platforms.

@lukemulks
Copy link
Collaborator Author

lukemulks commented Feb 14, 2017 via email

@lukemulks
Copy link
Collaborator Author

lukemulks commented Feb 14, 2017

Was able to pull a debug report from the player after catching an ad:

 {
"ns":"yt",

"el":"detailpage",

"cpn":"iDbFWs0RbuoU9Qwu",

"docid":"3GUvmvsKZII",

"ver":2,

"referrer":null,

"cmt":"0",

"plid":"AAVId9tGSJpVzeBz",

"ei":"pKaiWObWHtSS-gPAwb6oAw",

"fmt":"247",

"fs":"0",

"rt":"95.036",

"of":"Un4PA43Tqx0WZgELxi1v6A",

"adformat":null,

"content_v":null,

"euri":"",

"lact":1,

"live":null,

"cl":"147070178",

"mos":0,

"osid":null,

"state":"48",

"vm":"CAEQAQ",

"volume":100,

"c":"WEB",

"cver":"1.20170209",

"cplayer":"UNIPLAYER",

"cbr":"Chrome",

"cbrver":"56.0.2924.76",

"cos":"Windows",

"cosver":"10.0",

"hl":"en_US",

"cr":"US",

"len":"738",

"fexp":"9407610,9419452,9422596,9428398,9431012,9433221,9434046,9434289,9434905,9439580,9441513,9443249,9446054,9446364,9449034,9449243,9450059,9450184,9450989,9451345,9451367,9451491,9451873,9452307,9453002,9453177,9456017,9456640,9457095,9457141,9457449,9457494,9458325,9458868,9460170,9460261,9460440,9460727,9461561,9461746,9461757,9461984,9462282,9462496,9462541,9462838,9463021",

"afmt":"251",

"lct":"0.000",

"lsk":true,

"lmf":false,

"lbw":"3827532.076",

"lhd":"0.325",

"lst":"0.000",

"laa":"",

"lva":"",

"lar":

"itag=251,seg=0,range=1527-65535,time=0.0-4.3",

"lvr":"itag=247,seg=0,range=2715-400651,time=0.0-2.4",

"lvh":"r5---sn-o097znll",

"preroll":"1",

"ismb":10710000,

"debug_videoId":"3GUvmvsKZII",

"ad_ns":"yt",

"ad_el":"adunit",

"ad_cpn":"iiL5bhWMhwHwdAa3",

"ad_docid":"i-WcL4pWlGs",

"ad_ver":2,

"ad_referrer":null,

"ad_cmt":"7.373",

"ad_plid":"AAVId9tRvtNSP9DD",

"ad_ei":"paaiWOaBFsbX-wPvnLLYBQ",

"ad_fmt":"247",

"ad_fs":"0",

"ad_rt":"94.738",

"ad_of":"GC6OCn1lTVgpgJyrp2hYjw",

"ad_adformat":"15_2_1",

"ad_content_v":"3GUvmvsKZII",

"ad_euri":"",

"ad_lact":4,

"ad_live":null,

"ad_cl":"147070178",

"ad_mos":0,

"ad_osid":null,

"ad_state":"4",

"ad_vm":"CAEQAA",

"ad_volume":100,

"ad_c":"WEB",

"ad_cver":"1.20170209",

"ad_cplayer":"UNIPLAYER",

"ad_cbr":"Chrome",

"ad_cbrver":"56.0.2924.76",

"ad_cos":"Windows",

"ad_cosver":"10.0",

"ad_autoplay":"1",

"ad_delay":28,"

ad_hl":"en_US",

"ad_cr":"US",

"ad_uga":"m33",

"ad_len":"30.061",

"ad_fexp":"9407610,9419452,9422596,9428398,9431012,9433221,9434046,9434289,9434905,9439580,9441513,9443249,9446054,9446364,9449034,9449243,9450059,9450184,9450989,9451345,9451367,9451491,9451873,9452307,9453002,9453177,9456017,9456640,9457095,9457141,9457449,9457494,9458325,9458868,9460170,9460261,9460440,9460727,9461561,9461746,9461757,9461984,9462282,9462496,9462541,9462838,9463021",

"ad_afmt":"251",

"ad_vct":"7.373",

"ad_vd":"30.061",

"ad_vpl":"0.000-7.373,",

"ad_vbu":"0.000-30.061,",

"ad_vpa":true,

"ad_vsk":false,

"ad_ven":false,

"ad_vpr":1,

"ad_vrs":4,

"ad_vns":2,

"ad_vec":null,

"ad_vvol":1,

"ad_lct":"7.373",

"ad_lsk":false,

"ad_lmf":false,

"ad_lbw":"3827532.076",

"ad_lhd":"0.141",

"ad_lst":"0.000",

"ad_laa":"itag=251,seg=3,range=397650-398536,time=30.0-30.0",

"ad_lva":"itag=247,seg=5,range=3381524-3439586,time=26.7-30.0",

"ad_lar":"itag=251,seg=3,range=397650-398536,time=30.0-30.0",

"ad_lvr":"itag=247,seg=5,range=3381524-3439586,time=26.7-30.0",

"ad_lvh":"r3---sn-n4v7sne7",

"ad_lab":"0.000-30.061,",

"ad_lvb":"0.000-30.029,",

"ad_debug_videoId":"i-WcL4pWlGs",

"0sz":false,

"op":"1",

"yof":false,

"dis":"",

"gpu":"ANGLE_(Intel(R)_HD_Graphics_530_Direct3D11_vs_5_0_ps_5_0)",

"cgr":true,

"debug_playbackQuality":"hd720",

"debug_date":"Mon Feb 13 2017 22:43:16 GMT-0800 (Pacific Standard Time)"

}

@lukemulks
Copy link
Collaborator Author

lukemulks commented Feb 17, 2017

Ok, @bbondy @bridiver I'm officially at my breaking point with the YT ad situation.

There's a ton of info braindumped above, but I'll recap below:

02.10 - YT updated their player.
-Added new anti-adblocking flags
-Updated their adblocking policy for devs
-Users that have a Youtube ad blocking extension in chrome also reported failure around this time.

Only users that are logged in experience the issues w/ad blocking in YT.

I've compared uBlock, AdBlock and AdBlock Plus blocking to ours, and am curious about the following:

-When was the last update for our Easylist file (or does this auto-update)?
-When I go to about:adblock in Brave, it mentions 02.15.17 for the last update. Not sure if that applies specifically to the Easylist though (the Easylist w/o cosmetics list was updated on 02.17)
-AdBlock/Adblock Plus and uBlock both block YT ads for authenticated users.

After comparing the traffic, I went into about:adblock in brave and made the following custom rules to match (minus cosmetic element hiding, etc):

=adunit&
/api/ads/*
/googleads.
/pubads.
_reklama_$domain=~youtube.com

||2mdn.net^$object-subrequest,third-party,domain=youtube.com
||doubleclick.net^$third-party,domain=youtube.com|youtube-nocookie.com
||doubleclick.net^*/pfadx/app.ytpwatch.$third-party
||doubleclick.net^*/pfadx/com.ytpwatch.$third-party
||doubleclick.net^*/pfadx/embed.ytpwatch.$third-party
||doubleclick.net^*;afv_flvurl=http://cdn.c.ooyala.com/$third-party
||d2mq0uzafv8ytp.cloudfront.net^
||fwmrm.net^$~object-subrequest,third-party
||google.com/jsapi?autoload=*%22ads%22$script,domain=youtube.com
||google.com/pagead/
||googlesyndication.com/safeframe/
||innovid.com^$third-party
||lytpdzqyiygthvxlmgblonknzrctcwsjycmlcczifxbkquknsr.com^$third-party
||pagead2.googlesyndication.com^$~object-subrequest
||phobos.apple.com^$image,domain=youtube.com
||proxy-youtube.net/mih_
||proxy-youtube.net/myiphide_
||tawgiuioeaovaozwassucoydtrsellartytpikvcjpuwpagwfv.com^$third-party
||youtube-mp3.org/acode/
||ytimg.com^*/new_watch_background.jpg?$domain=youtube.com
||ytimg.com^*/new_watch_background_*.jpg?$domain=youtube.com
||ytimg.com^*_banner$domain=youtube.com
||ytmnd.com/ugh
||yts.ag/images/vpnanim.gif
||topspin.net/secure/media/$image,domain=youtube.com

@@||g.doubleclick.net/gpt/pubads_impl_$script
@@||gstatic.com^$third-party
@@||google.com/jsapi$script,third-party
@@||googleads.g.doubleclick.net/pagead/viewthroughconversion$subdocument,image
@@||youtube.com/iframe_api$script,third-party
@@||youtube.com/player_api$script,third-party
@@||getlinkyoutube.com^*/adframe.js
@@||s.ytimg.com/yts/swfbin/player-*/watch_as3.swf$object,domain=youtube.com
@@||youtube.com/yt/css/www-advertise.css
@@||youtube.com/yt/js/www-advertise.min.js$domain=youtube.com
@@||youtube.com/ads/preferences/$popup
@@||youtube.com/yt/advertise/medias/images/$image
@@||youtube.com^*_adsense_$xmlhttprequest
@@||ytimg.com/yts/jsbin/$script
@@||ytimg.com/yts/img/*/display-ads$image,domain=youtube.com
@@||ytimg.com/yts/img/channels/*_banner-*.jpg$domain=youtube.com
@@||ytimg.com/yts/img/channels/*_banner-*.png$domain=youtube.com
@@||ytimg.com^*/channels4_banner.jpg?$domain=youtube.com
@@||ytimg.com^*/channels4_banner_hd.jpg?$domain=youtube.com
@@||google.com/ads/js/$script,domain=incentiveswidget.appspot.com

There are some listed above that are potentially duplicates, but I went overboard just in case.

I started exploring the extensions in Chrome (dev mode for extension - ctrl+f8 dev tools), and in uBlock's advanced settings:

Ublock origin has some behind-the-scene permanent rules setup

behind-the-scene * 3p noop
behind-the-scene * 3p-frame noop

@lukemulks
Copy link
Collaborator Author

Moving this issue to adblock-lists for next steps (based on testing and checks from today) brave/adblock-lists#3

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
feature/adblock help wanted The PR/issue opener needs help to complete/report the task. site-bug
Projects
None yet
Development

No branches or pull requests

2 participants