Skip to content

Commit

Permalink
Merge pull request #11 from PubMatic-OpenWrap/UOE-4350_SameSite
Browse files Browse the repository at this point in the history
Uoe 4350 same site
  • Loading branch information
PubMatic-OpenWrap authored Aug 19, 2019
2 parents 0ac949b + 5c65a82 commit e6b82e9
Show file tree
Hide file tree
Showing 13 changed files with 123 additions and 30 deletions.
4 changes: 2 additions & 2 deletions adapters/adform/adform_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ import (

"fmt"

"github.com/mxmCherry/openrtb"
"github.com/PubMatic-OpenWrap/prebid-server/adapters"
"github.com/PubMatic-OpenWrap/prebid-server/config"
"github.com/PubMatic-OpenWrap/prebid-server/openrtb_ext"
"github.com/mxmCherry/openrtb"
)

func TestJsonSamples(t *testing.T) {
Expand Down Expand Up @@ -198,7 +198,7 @@ func preparePrebidRequest(serverUrl string, t *testing.T) *pbs.PBSRequest {
pbsCookie := usersync.ParsePBSCookieFromRequest(prebidHttpRequest, &config.HostCookie{})
pbsCookie.TrySync("adform", adformTestData.buyerUID)
fakeWriter := httptest.NewRecorder()
pbsCookie.SetCookieOnResponse(fakeWriter, "", time.Minute)
pbsCookie.SetCookieOnResponse(fakeWriter, prebidHttpRequest, "", time.Minute)
prebidHttpRequest.Header.Add("Cookie", fakeWriter.Header().Get("Set-Cookie"))

cacheClient, _ := dummycache.New()
Expand Down
4 changes: 2 additions & 2 deletions adapters/appnexus/appnexus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ import (

"fmt"

"github.com/mxmCherry/openrtb"
"github.com/PubMatic-OpenWrap/prebid-server/adapters"
"github.com/PubMatic-OpenWrap/prebid-server/adapters/adapterstest"
"github.com/PubMatic-OpenWrap/prebid-server/config"
"github.com/mxmCherry/openrtb"
)

func TestJsonSamples(t *testing.T) {
Expand Down Expand Up @@ -363,7 +363,7 @@ func TestAppNexusBasicResponse(t *testing.T) {
pc := usersync.ParsePBSCookieFromRequest(req, &config.HostCookie{})
pc.TrySync("adnxs", andata.buyerUID)
fakewriter := httptest.NewRecorder()
pc.SetCookieOnResponse(fakewriter, "", 90*24*time.Hour)
pc.SetCookieOnResponse(fakewriter, req, "", 90*24*time.Hour)
req.Header.Add("Cookie", fakewriter.Header().Get("Set-Cookie"))

cacheClient, _ := dummycache.New()
Expand Down
4 changes: 2 additions & 2 deletions adapters/audienceNetwork/facebook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ import (

"fmt"

"github.com/mxmCherry/openrtb"
"github.com/PubMatic-OpenWrap/prebid-server/adapters"
"github.com/PubMatic-OpenWrap/prebid-server/config"
"github.com/mxmCherry/openrtb"
)

type tagInfo struct {
Expand Down Expand Up @@ -209,7 +209,7 @@ func GenerateBidRequestForTestData(fbdata bidInfo, url string) (*pbs.PBSRequest,
pc := usersync.ParsePBSCookieFromRequest(req, &config.HostCookie{})
pc.TrySync("audienceNetwork", fbdata.buyerUID)
fakewriter := httptest.NewRecorder()
pc.SetCookieOnResponse(fakewriter, "", 90*24*time.Hour)
pc.SetCookieOnResponse(fakewriter, req, "", 90*24*time.Hour)
req.Header.Add("Cookie", fakewriter.Header().Get("Set-Cookie"))

cacheClient, _ := dummycache.New()
Expand Down
4 changes: 2 additions & 2 deletions adapters/lifestreet/lifestreet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ import (

"fmt"

"github.com/mxmCherry/openrtb"
"github.com/PubMatic-OpenWrap/prebid-server/adapters"
"github.com/PubMatic-OpenWrap/prebid-server/config"
"github.com/mxmCherry/openrtb"
)

type lsTagInfo struct {
Expand Down Expand Up @@ -227,7 +227,7 @@ func TestLifestreetBasicResponse(t *testing.T) {

pc := usersync.ParsePBSCookieFromRequest(req, &config.HostCookie{})
fakewriter := httptest.NewRecorder()
pc.SetCookieOnResponse(fakewriter, "", 90*24*time.Hour)
pc.SetCookieOnResponse(fakewriter, req, "", 90*24*time.Hour)
req.Header.Add("Cookie", fakewriter.Header().Get("Set-Cookie"))

cacheClient, _ := dummycache.New()
Expand Down
4 changes: 2 additions & 2 deletions adapters/pubmatic/pubmatic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ import (
"testing"
"time"

"github.com/mxmCherry/openrtb"
"github.com/PubMatic-OpenWrap/prebid-server/adapters"
"github.com/PubMatic-OpenWrap/prebid-server/adapters/adapterstest"
"github.com/PubMatic-OpenWrap/prebid-server/cache/dummycache"
"github.com/PubMatic-OpenWrap/prebid-server/config"
"github.com/PubMatic-OpenWrap/prebid-server/pbs"
"github.com/PubMatic-OpenWrap/prebid-server/usersync"
"github.com/mxmCherry/openrtb"
)

func TestJsonSamples(t *testing.T) {
Expand Down Expand Up @@ -656,7 +656,7 @@ func TestPubmaticSampleRequest(t *testing.T) {
pc := usersync.ParsePBSCookieFromRequest(httpReq, &config.HostCookie{})
pc.TrySync("pubmatic", "12345")
fakewriter := httptest.NewRecorder()
pc.SetCookieOnResponse(fakewriter, "", 90*24*time.Hour)
pc.SetCookieOnResponse(fakewriter, httpReq, "", 90*24*time.Hour)
httpReq.Header.Add("Cookie", fakewriter.Header().Get("Set-Cookie"))

cacheClient, _ := dummycache.New()
Expand Down
4 changes: 2 additions & 2 deletions adapters/pulsepoint/pulsepoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ import (
"testing"
"time"

"github.com/mxmCherry/openrtb"
"github.com/PubMatic-OpenWrap/prebid-server/adapters"
"github.com/PubMatic-OpenWrap/prebid-server/adapters/adapterstest"
"github.com/PubMatic-OpenWrap/prebid-server/cache/dummycache"
"github.com/PubMatic-OpenWrap/prebid-server/config"
"github.com/PubMatic-OpenWrap/prebid-server/openrtb_ext"
"github.com/PubMatic-OpenWrap/prebid-server/pbs"
"github.com/PubMatic-OpenWrap/prebid-server/usersync"
"github.com/mxmCherry/openrtb"
)

/**
Expand Down Expand Up @@ -226,7 +226,7 @@ func SampleRequest(numberOfImpressions int, t *testing.T) *pbs.PBSRequest {
pc := usersync.ParsePBSCookieFromRequest(httpReq, &config.HostCookie{})
pc.TrySync("pulsepoint", "pulsepointUser123")
fakewriter := httptest.NewRecorder()
pc.SetCookieOnResponse(fakewriter, "", 90*24*time.Hour)
pc.SetCookieOnResponse(fakewriter, httpReq, "", 90*24*time.Hour)
httpReq.Header.Add("Cookie", fakewriter.Header().Get("Set-Cookie"))
// parse the http request
cacheClient, _ := dummycache.New()
Expand Down
4 changes: 2 additions & 2 deletions adapters/rubicon/rubicon_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ import (

"strings"

"github.com/mxmCherry/openrtb"
"github.com/PubMatic-OpenWrap/prebid-server/adapters"
"github.com/PubMatic-OpenWrap/prebid-server/config"
"github.com/PubMatic-OpenWrap/prebid-server/openrtb_ext"
"github.com/mxmCherry/openrtb"
)

type rubiAppendTrackerUrlTestScenario struct {
Expand Down Expand Up @@ -945,7 +945,7 @@ func CreatePrebidRequest(server *httptest.Server, t *testing.T) (an *RubiconAdap
pc := usersync.ParsePBSCookieFromRequest(req, &config.HostCookie{})
pc.TrySync("rubicon", rubidata.buyerUID)
fakewriter := httptest.NewRecorder()
pc.SetCookieOnResponse(fakewriter, "", 90*24*time.Hour)
pc.SetCookieOnResponse(fakewriter, req, "", 90*24*time.Hour)
req.Header.Add("Cookie", fakewriter.Header().Get("Set-Cookie"))

cacheClient, _ := dummycache.New()
Expand Down
4 changes: 2 additions & 2 deletions adapters/sovrn/sovrn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import (
"net/http/httptest"
"testing"

"github.com/mxmCherry/openrtb"
"github.com/PubMatic-OpenWrap/prebid-server/pbs"
"github.com/PubMatic-OpenWrap/prebid-server/usersync"
"github.com/mxmCherry/openrtb"

"context"
"net/http"
Expand Down Expand Up @@ -188,7 +188,7 @@ func SampleSovrnRequest(numberOfImpressions int, t *testing.T) *pbs.PBSRequest {
pc := usersync.ParsePBSCookieFromRequest(httpReq, &config.HostCookie{})
pc.TrySync("sovrn", testSovrnUserId)
fakewriter := httptest.NewRecorder()
pc.SetCookieOnResponse(fakewriter, "", 90*24*time.Hour)
pc.SetCookieOnResponse(fakewriter, httpReq, "", 90*24*time.Hour)
httpReq.Header.Add("Cookie", fakewriter.Header().Get("Set-Cookie"))
// parse the http request
cacheClient, _ := dummycache.New()
Expand Down
14 changes: 11 additions & 3 deletions endpoints/cookie_sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,16 @@ func (deps *cookieSyncDeps) Endpoint(w http.ResponseWriter, r *http.Request, _ h
parsedReq.Bidders = append(parsedReq.Bidders, string(bidder))
}
}
isBrowserApplicable := usersync.IsBrowserApplicableForSameSite(r)
needSyncupForSameSite := false
if isBrowserApplicable {
_, err1 := r.Cookie(usersync.SameSiteCookieName)
if err1 == http.ErrNoCookie {
needSyncupForSameSite = true
}
}

parsedReq.filterExistingSyncs(deps.syncers, userSyncCookie)
parsedReq.filterExistingSyncs(deps.syncers, userSyncCookie, needSyncupForSameSite)
adapterSyncs := make(map[openrtb_ext.BidderName]bool)
for _, b := range parsedReq.Bidders {
// assume all bidders will be GDPR blocked
Expand Down Expand Up @@ -193,15 +201,15 @@ type cookieSyncRequest struct {
Limit int `json:"limit"`
}

func (req *cookieSyncRequest) filterExistingSyncs(valid map[openrtb_ext.BidderName]usersync.Usersyncer, cookie *usersync.PBSCookie) {
func (req *cookieSyncRequest) filterExistingSyncs(valid map[openrtb_ext.BidderName]usersync.Usersyncer, cookie *usersync.PBSCookie, needSyncupForSameSite bool) {
for i := 0; i < len(req.Bidders); i++ {
thisBidder := req.Bidders[i]
//added hack to support to old wrapper versions having indexExchange as partner
//TODO: Remove when a stable version is released
if thisBidder == "indexExchange" {
thisBidder = "ix"
}
if syncer, isValid := valid[openrtb_ext.BidderName(thisBidder)]; !isValid || cookie.HasLiveSync(syncer.FamilyName()) {
if syncer, isValid := valid[openrtb_ext.BidderName(thisBidder)]; !isValid || (cookie.HasLiveSync(syncer.FamilyName()) && !needSyncupForSameSite) {
req.Bidders = append(req.Bidders[:i], req.Bidders[i+1:]...)
i--
}
Expand Down
4 changes: 2 additions & 2 deletions endpoints/setuid.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import (
"net/http"
"time"

"github.com/julienschmidt/httprouter"
"github.com/PubMatic-OpenWrap/prebid-server/analytics"
"github.com/PubMatic-OpenWrap/prebid-server/config"
"github.com/PubMatic-OpenWrap/prebid-server/gdpr"
"github.com/PubMatic-OpenWrap/prebid-server/openrtb_ext"
"github.com/PubMatic-OpenWrap/prebid-server/pbsmetrics"
"github.com/PubMatic-OpenWrap/prebid-server/usersync"
"github.com/julienschmidt/httprouter"
)

func NewSetUIDEndpoint(cfg config.HostCookie, perms gdpr.Permissions, pbsanalytics analytics.PBSAnalyticsModule, metrics pbsmetrics.MetricsEngine) httprouter.Handle {
Expand Down Expand Up @@ -76,7 +76,7 @@ func NewSetUIDEndpoint(cfg config.HostCookie, perms gdpr.Permissions, pbsanalyti
so.Success = true
}

pc.SetCookieOnResponse(w, cfg.Domain, cookieTTL)
pc.SetCookieOnResponse(w, r, cfg.Domain, cookieTTL)
})
}

Expand Down
6 changes: 3 additions & 3 deletions pbs/usersync.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import (
"strings"
"time"

"github.com/golang/glog"
"github.com/julienschmidt/httprouter"
"github.com/PubMatic-OpenWrap/prebid-server/analytics"
"github.com/PubMatic-OpenWrap/prebid-server/config"
"github.com/PubMatic-OpenWrap/prebid-server/pbsmetrics"
"github.com/PubMatic-OpenWrap/prebid-server/ssl"
"github.com/PubMatic-OpenWrap/prebid-server/usersync"
"github.com/golang/glog"
"github.com/julienschmidt/httprouter"
)

// Recaptcha code from https://github.com/haisum/recaptcha/blob/master/recaptcha.go
Expand Down Expand Up @@ -95,7 +95,7 @@ func (deps *UserSyncDeps) OptOut(w http.ResponseWriter, r *http.Request, _ httpr
pc := usersync.ParsePBSCookieFromRequest(r, deps.HostCookieConfig)
pc.SetPreference(optout == "")

pc.SetCookieOnResponse(w, deps.HostCookieConfig.Domain, deps.HostCookieConfig.TTLDuration())
pc.SetCookieOnResponse(w, r, deps.HostCookieConfig.Domain, deps.HostCookieConfig.TTLDuration())
if optout == "" {
http.Redirect(w, r, deps.HostCookieConfig.OptInURL, 301)
} else {
Expand Down
67 changes: 62 additions & 5 deletions usersync/cookie.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,27 @@ import (
"encoding/json"
"errors"
"net/http"
"strconv"
"strings"
"time"

"github.com/PubMatic-OpenWrap/prebid-server/config"
"github.com/PubMatic-OpenWrap/prebid-server/openrtb_ext"
)

// DEFAULT_TTL is the default amount of time which a cookie is considered valid.
const DEFAULT_TTL = 14 * 24 * time.Hour
const UID_COOKIE_NAME = "uids"
const (
// DEFAULT_TTL is the default amount of time which a cookie is considered valid.
DEFAULT_TTL = 14 * 24 * time.Hour
UID_COOKIE_NAME = "uids"
chromeStr = "Chrome/"
chromeiOSStr = "CriOS/"
chromeMinVer = 67
chromeStrLen = len(chromeStr)
chromeiOSStrLen = len(chromeiOSStr)
SameSiteCookieName = "SSCookie"
SameSiteCookieValue = "1"
SameSiteAttribute = "; SameSite=None"
)

// customBidderTTLs stores rules about how long a particular UID sync is valid for each bidder.
// If a bidder does a cookie sync *without* listing a rule here, then the DEFAULT_TTL will be used.
Expand Down Expand Up @@ -160,12 +172,57 @@ func (cookie *PBSCookie) GetId(bidderName openrtb_ext.BidderName) (id string, ex
}

// SetCookieOnResponse is a shortcut for "ToHTTPCookie(); cookie.setDomain(domain); setCookie(w, cookie)"
func (cookie *PBSCookie) SetCookieOnResponse(w http.ResponseWriter, domain string, ttl time.Duration) {
func (cookie *PBSCookie) SetCookieOnResponse(w http.ResponseWriter, r *http.Request, domain string, ttl time.Duration) {
httpCookie := cookie.ToHTTPCookie(ttl)
if domain != "" {
httpCookie.Domain = domain
}
http.SetCookie(w, httpCookie)
cookieStr := httpCookie.String()
var sameSiteCookie *http.Cookie
if IsBrowserApplicableForSameSite(r) {
cookieStr += SameSiteAttribute
sameSiteCookie = &http.Cookie{
Name: SameSiteCookieName,
Value: SameSiteCookieValue,
Expires: time.Now().Add(ttl),
Path: "/",
}
sameSiteCookieStr := sameSiteCookie.String()
sameSiteCookieStr += SameSiteAttribute
w.Header().Add("Set-Cookie", sameSiteCookieStr)
}
if cookieStr != "" {
w.Header().Add("Set-Cookie", cookieStr)
}
}

// IsBrowserApplicableForSameSite function checks if browser is Chrome and browser version is greater than the minimum version for adding the SameSite attribute
func IsBrowserApplicableForSameSite(req *http.Request) bool {
result := false
ua := req.UserAgent()

index := strings.Index(ua, chromeStr)
criOSIndex := strings.Index(ua, chromeiOSStr)
if index != -1 {
result = checkChromeBrowserVersion(ua, index, chromeStrLen)
} else if criOSIndex != -1 {
result = checkChromeBrowserVersion(ua, criOSIndex, chromeiOSStrLen)
}
return result
}

func checkChromeBrowserVersion(ua string, index int, chromeStrLength int) bool {
result := false
vIndex := index + chromeStrLength
dotIndex := strings.Index(ua[vIndex:], ".")
if dotIndex == -1 {
dotIndex = len(ua[vIndex:])
}
version, _ := strconv.Atoi(ua[vIndex : vIndex+dotIndex])
if version >= chromeMinVer {
result = true
}
return result
}

// Unsync removes the user's ID for the given family from this cookie.
Expand Down
30 changes: 29 additions & 1 deletion usersync/cookie_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/json"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"

Expand Down Expand Up @@ -353,11 +354,38 @@ func newSampleCookie() *PBSCookie {

func writeThenRead(cookie *PBSCookie) *PBSCookie {
w := httptest.NewRecorder()
cookie.SetCookieOnResponse(w, "mock-domain", 90*24*time.Hour)
req := httptest.NewRequest("GET", "http://www.prebid.com", nil)
cookie.SetCookieOnResponse(w, req, "mock-domain", 90*24*time.Hour)
writtenCookie := w.HeaderMap.Get("Set-Cookie")

header := http.Header{}
header.Add("Cookie", writtenCookie)
request := http.Request{Header: header}
return ParsePBSCookieFromRequest(&request, &config.HostCookie{})
}

func TestSetCookieOnResponseForSameSiteNone(t *testing.T) {
cookie := newSampleCookie()
w := httptest.NewRecorder()
req := httptest.NewRequest("GET", "http://www.prebid.com", nil)
req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36")
cookie.SetCookieOnResponse(w, req, "mock-domain", 90*24*time.Hour)
writtenCookie := w.HeaderMap.Get("Set-Cookie")
t.Log("Set-Cookie is: ", writtenCookie)
if !strings.Contains(writtenCookie, "SSCookie=1") {
t.Error("Set-Cookie should contain SSCookie=1")
}
}

func TestSetCookieOnResponseForOlderChromeVersion(t *testing.T) {
cookie := newSampleCookie()
w := httptest.NewRecorder()
req := httptest.NewRequest("GET", "http://www.prebid.com", nil)
req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3770.142 Safari/537.36")
cookie.SetCookieOnResponse(w, req, "mock-domain", 90*24*time.Hour)
writtenCookie := w.HeaderMap.Get("Set-Cookie")
t.Log("Set-Cookie is: ", writtenCookie)
if strings.Contains(writtenCookie, "SameSite=none") {
t.Error("Set-Cookie should not contain SameSite=none")
}
}

0 comments on commit e6b82e9

Please sign in to comment.