Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Offer same-site pixel "API" as alternative to a JavaScript API #71

Open
johnwilander opened this issue Feb 22, 2021 · 8 comments
Open
Assignees

Comments

@johnwilander
Copy link
Collaborator

We should offer a same-site pixel "API" on the attribute-on side of PCM to 1) remove the dependency on third-party pixels, and 2) not introduce a dependency on JavaScript. During a recent Privacy CG call, at least three people brought up that some advertisers/merchants/click destinations are very reluctant to deploy JavaScript for attribution purposes. So I suggested that we match the functionality of the JavaScript API (or parts of it) with a same-site “pixel” way of triggering attribution.

@annevk
Copy link

annevk commented Mar 11, 2021

I wonder if instead of a .well-known request this could be a <meta> element that captures the conversion. This could be included on the (presumably static) conversion page and once the user agent appends it to the document it would register the conversion.

@johnwilander
Copy link
Collaborator Author

johnwilander commented Mar 11, 2021

I wonder if instead of a .well-known request this could be a <meta> element that captures the conversion. This could be included on the (presumably static) conversion page and once the user agent appends it to the document it would register the conversion.

Thanks, Anne! Now I see what you're saying. I don't think this would work because many advertiser sites want to trigger attribution for events beyond page loads. It could be for clicks to add something to a cart, for reaching a certain level of engagement such as level N in a game or configuring a car, or for stages in a checkout flow. So whatever we build has to support in-page events.

@annevk
Copy link

annevk commented Mar 11, 2021

How would you have those kind of events without navigations or JavaScript?

@jackfrankland
Copy link

Presumably in order for the pixel to be dynamically added to the page it would require some JavaScript right? If the pixel/tag is injected with a tag manager to avoid develoepr involvement, I think it's just as easy for the tag to be a script which interfaces with the JS API. This isn't to say it couldn't also be an img tag, but I don't see much benefit.

Having an additonal meta tag makes more sense to me, where the page's loading signifies a conversion itself (i.e. order confirmation page), and doesn't require JS or a tag in a tag manager.

@johnwilander
Copy link
Collaborator Author

How would you have those kind of events without navigations or JavaScript?

I don't think these pages are free of JavaScript. It's just that they don't want to include any JavaScript someone else hands them. That was my interpretation of it. I don't know if they generate markup in script or pull in markup from servers. @kdeqc, would it work if we tie this alternative "API" to page loads?

@TanviHacks TanviHacks removed the agenda+ Request to add this issue to the agenda of our next telcon or F2F label Apr 5, 2021
@TanviHacks TanviHacks added the agenda+ Request to add this issue to the agenda of our next telcon or F2F label Jun 7, 2021
@kdeqc
Copy link

kdeqc commented Jun 10, 2021

Sorry - didn't catch this earlier. To answer, though, the pages typically do have JS, but adding someone else's JS is seen as a bit of a security risk and/or sometimes difficult to debug. The folks who often manage ad campaigns and such aren't generally web developers so it can be an extra challenge for some folks too.

@erik-anderson erik-anderson removed the agenda+ Request to add this issue to the agenda of our next telcon or F2F label Jun 10, 2021
@annevk
Copy link

annevk commented Jun 17, 2021

I feel like I'm still missing something. Why would they not be handed data that can be passed into the API? Why does the data have to be markup that is injected into the page that then does a well-known request? Maybe someone can explain the full setup here?

@johnwilander
Copy link
Collaborator Author

johnwilander commented Jun 17, 2021

I'll let Kristen speak to merchants'/site owners' willingness to deploy pixels vs JavaScript calls. As for the request and required redirect, it actually gives the site owner a chance to control who can trigger attribution. Their server gets the final decision on any conversion triggered by the same-site pixel, or at least has a chance to make the final decision. That's different from a JavaScript API which any code on the site can call without the site owner's knowledge. You could even have rogue web extensions call such an API.

Those are the pros and cons we've discussed. I personally like the fact that a pixel "API" has zero risk of causing interoperability issues with browsers who don't support PCM or Attribution Reporting API. No feature detection or such needed. I.e. it has maximum chance of being easy to adopt.

webkit-commit-queue pushed a commit to WebKit/WebKit that referenced this issue Nov 18, 2021
…thout cross-site requests to the click source

https://bugs.webkit.org/show_bug.cgi?id=233173
<rdar://79426605>

Reviewed by Alex Christensen.

Source/WebCore:

This patch enables click destination sites a non-JavaScript way to fire triggering
events without a requirement to make cross-site requests to source sites. This is
referred to as a "same-site pixel API" and has been discussed in W3C Privacy CG:
privacycg/private-click-measurement#71

The reason why some merchants want such an "API" is reluctance to deploy new
JavaScript on their sites. In some industries it's even a compliance issue. Legacy
"pixels" are however accepted and so a same-site "pixel" can work for them.

Test: http/tests/privateClickMeasurement/triggering-event-with-attribution-source-through-fetch-keepalive.html

* html/HTMLAnchorElement.cpp:
(WebCore::HTMLAnchorElement::handleClick):
    This change is because of clarification in naming:
    - attributionReportSourceURL to attributionReportClickSourceURL
* loader/PrivateClickMeasurement.cpp:
(WebCore::PrivateClickMeasurement::parseAttributionRequestQuery):
    New function that parses out query string parameters.
(WebCore::PrivateClickMeasurement::parseAttributionRequest):
    Now calls the new PrivateClickMeasurement::parseAttributionRequestQuery()
    which handles data coming in in query parameters, in this case
    the new parameter "attributionSource."
(WebCore::PrivateClickMeasurement::attributionReportClickSourceURL const):
    New name.
(WebCore::PrivateClickMeasurement::attributionReportClickDestinationURL const):
    New name.
(WebCore::PrivateClickMeasurement::attributionReportJSON const):
    Now uses the constant privateClickMeasurementVersion.
(WebCore::PrivateClickMeasurement::tokenSignatureJSON const):
    Now uses the constant privateClickMeasurementVersion.
(WebCore::PrivateClickMeasurement::attributionReportSourceURL const): Deleted.
    Renamed attributionReportClickSourceURL.
(WebCore::PrivateClickMeasurement::attributionReportAttributeOnURL const): Deleted.
    Renamed attributionReportClickDestinationURL.
* loader/PrivateClickMeasurement.h:
(WebCore::PrivateClickMeasurement::sourceSecretToken const):
    New name.
(WebCore::PrivateClickMeasurement::AttributionTriggerData::encode const):
(WebCore::PrivateClickMeasurement::AttributionTriggerData::decode):
    Encoding and decoding of the new field sourceRegistrableDomain.
(WebCore::PrivateClickMeasurement::sourceUnlinkableToken const): Deleted.
    Renamed sourceSecretToken.
    Note that it was always the secret token used, just bad renaming earlier.

Source/WebKit:

This patch enables click destination sites a non-JavaScript way to fire triggering
events without a requirement to make cross-site requests to source sites. This is
referred to as a "same-site pixel API" and has been discussed in W3C Privacy CG:
privacycg/private-click-measurement#71

The reason why some merchants want such an "API" is reluctance to deploy new
JavaScript on their sites. In some industries it's even a compliance issue. Legacy
"pixels" are however accepted and so a same-site "pixel" can work for them.

* NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementDatabase.cpp:
(WebKit::PCM::Database::insertPrivateClickMeasurement):
    These changes are just a correction of a function name:
    - sourceUnlinkableToken() to sourceSecretToken()
    Note that it was always the secret token used, just bad renaming earlier.
* NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManager.cpp:
(WebKit::PrivateClickMeasurementManager::handleAttribution):
    Now checks if the incoming WebCore::PrivateClickMeasurement::AttributionTriggerData
    carries a sourceRegistrableDomain. If so, it accepts that domain as the source site
    for attribution if the triggering event was same-site as the first-party.
(WebKit::PrivateClickMeasurementManager::attribute):
(WebKit::PrivateClickMeasurementManager::fireConversionRequest):
    These changes are just a correction of a function name:
    - sourceUnlinkableToken() to sourceSecretToken()
    Note that it was always the secret token used, just bad renaming earlier.
(WebKit::PrivateClickMeasurementManager::fireConversionRequestImpl):
    These changes are because of clarification in naming:
    - attributionReportSourceURL to attributionReportClickSourceURL
    - attributionReportAttributeOnURL to attributionReportClickDestinationURL
* NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManager.h:
* NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementStore.cpp:
(WebKit::PCM::Store::attributePrivateClickMeasurement):
* NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementStore.h:

Source/WTF:

* wtf/URL.cpp:
(WTF::queryParameters):
    New convenience getter.
* wtf/URL.h:

Tools:

These changes are just a correction of a function name:
sourceUnlinkableToken() to sourceSecretToken()

* TestWebKitAPI/Tests/WebCore/PrivateClickMeasurement.cpp:
(TestWebKitAPI::TEST):
* TestWebKitAPI/Tests/WebCore/cocoa/PrivateClickMeasurementCocoa.mm:
(TestWebKitAPI::TEST):

LayoutTests:

* http/tests/privateClickMeasurement/resources/redirectToConversionWithAttributionSource.py: Added.
* http/tests/privateClickMeasurement/triggering-event-with-attribution-source-through-fetch-keepalive-expected.txt: Added.
* http/tests/privateClickMeasurement/triggering-event-with-attribution-source-through-fetch-keepalive.html: Added.



Canonical link: https://commits.webkit.org/244367@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@285967 268f45cc-cd09-0410-ab3c-d52691b4dbfc
annulen pushed a commit to qtwebkit/qtwebkit that referenced this issue Nov 19, 2021
…thout cross-site requests to the click source

https://bugs.webkit.org/show_bug.cgi?id=233173
<rdar://79426605>

Reviewed by Alex Christensen.

Source/WebCore:

This patch enables click destination sites a non-JavaScript way to fire triggering
events without a requirement to make cross-site requests to source sites. This is
referred to as a "same-site pixel API" and has been discussed in W3C Privacy CG:
privacycg/private-click-measurement#71

The reason why some merchants want such an "API" is reluctance to deploy new
JavaScript on their sites. In some industries it's even a compliance issue. Legacy
"pixels" are however accepted and so a same-site "pixel" can work for them.

Test: http/tests/privateClickMeasurement/triggering-event-with-attribution-source-through-fetch-keepalive.html

* html/HTMLAnchorElement.cpp:
(WebCore::HTMLAnchorElement::handleClick):
    This change is because of clarification in naming:
    - attributionReportSourceURL to attributionReportClickSourceURL
* loader/PrivateClickMeasurement.cpp:
(WebCore::PrivateClickMeasurement::parseAttributionRequestQuery):
    New function that parses out query string parameters.
(WebCore::PrivateClickMeasurement::parseAttributionRequest):
    Now calls the new PrivateClickMeasurement::parseAttributionRequestQuery()
    which handles data coming in in query parameters, in this case
    the new parameter "attributionSource."
(WebCore::PrivateClickMeasurement::attributionReportClickSourceURL const):
    New name.
(WebCore::PrivateClickMeasurement::attributionReportClickDestinationURL const):
    New name.
(WebCore::PrivateClickMeasurement::attributionReportJSON const):
    Now uses the constant privateClickMeasurementVersion.
(WebCore::PrivateClickMeasurement::tokenSignatureJSON const):
    Now uses the constant privateClickMeasurementVersion.
(WebCore::PrivateClickMeasurement::attributionReportSourceURL const): Deleted.
    Renamed attributionReportClickSourceURL.
(WebCore::PrivateClickMeasurement::attributionReportAttributeOnURL const): Deleted.
    Renamed attributionReportClickDestinationURL.
* loader/PrivateClickMeasurement.h:
(WebCore::PrivateClickMeasurement::sourceSecretToken const):
    New name.
(WebCore::PrivateClickMeasurement::AttributionTriggerData::encode const):
(WebCore::PrivateClickMeasurement::AttributionTriggerData::decode):
    Encoding and decoding of the new field sourceRegistrableDomain.
(WebCore::PrivateClickMeasurement::sourceUnlinkableToken const): Deleted.
    Renamed sourceSecretToken.
    Note that it was always the secret token used, just bad renaming earlier.

Source/WebKit:

This patch enables click destination sites a non-JavaScript way to fire triggering
events without a requirement to make cross-site requests to source sites. This is
referred to as a "same-site pixel API" and has been discussed in W3C Privacy CG:
privacycg/private-click-measurement#71

The reason why some merchants want such an "API" is reluctance to deploy new
JavaScript on their sites. In some industries it's even a compliance issue. Legacy
"pixels" are however accepted and so a same-site "pixel" can work for them.

* NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementDatabase.cpp:
(WebKit::PCM::Database::insertPrivateClickMeasurement):
    These changes are just a correction of a function name:
    - sourceUnlinkableToken() to sourceSecretToken()
    Note that it was always the secret token used, just bad renaming earlier.
* NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManager.cpp:
(WebKit::PrivateClickMeasurementManager::handleAttribution):
    Now checks if the incoming WebCore::PrivateClickMeasurement::AttributionTriggerData
    carries a sourceRegistrableDomain. If so, it accepts that domain as the source site
    for attribution if the triggering event was same-site as the first-party.
(WebKit::PrivateClickMeasurementManager::attribute):
(WebKit::PrivateClickMeasurementManager::fireConversionRequest):
    These changes are just a correction of a function name:
    - sourceUnlinkableToken() to sourceSecretToken()
    Note that it was always the secret token used, just bad renaming earlier.
(WebKit::PrivateClickMeasurementManager::fireConversionRequestImpl):
    These changes are because of clarification in naming:
    - attributionReportSourceURL to attributionReportClickSourceURL
    - attributionReportAttributeOnURL to attributionReportClickDestinationURL
* NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementManager.h:
* NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementStore.cpp:
(WebKit::PCM::Store::attributePrivateClickMeasurement):
* NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementStore.h:

Source/WTF:

* wtf/URL.cpp:
(WTF::queryParameters):
    New convenience getter.
* wtf/URL.h:

Tools:

These changes are just a correction of a function name:
sourceUnlinkableToken() to sourceSecretToken()

* TestWebKitAPI/Tests/WebCore/PrivateClickMeasurement.cpp:
(TestWebKitAPI::TEST):
* TestWebKitAPI/Tests/WebCore/cocoa/PrivateClickMeasurementCocoa.mm:
(TestWebKitAPI::TEST):

LayoutTests:

* http/tests/privateClickMeasurement/resources/redirectToConversionWithAttributionSource.py: Added.
* http/tests/privateClickMeasurement/triggering-event-with-attribution-source-through-fetch-keepalive-expected.txt: Added.
* http/tests/privateClickMeasurement/triggering-event-with-attribution-source-through-fetch-keepalive.html: Added.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@285967 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants