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

Commit

Permalink
Cors regression test (prebid#650)
Browse files Browse the repository at this point in the history
* Added a regression test for the cors bug.

* Fixed the test.

* Better cors regression test.
  • Loading branch information
dbemiller authored and hhhjort committed Aug 13, 2018
1 parent 9fb1e36 commit 80891c0
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 22 deletions.
48 changes: 26 additions & 22 deletions pbs_light.go
Original file line number Diff line number Diff line change
Expand Up @@ -736,28 +736,7 @@ func serve(revision string, cfg *config.Configuration) error {

pbc.InitPrebidCache(cfg.CacheURL.GetBaseURL())

// Fixes #648
//
// These CORS options pose a security risk... but it's a calculated one.
// People _must_ call us with "withCredentials" set to "true" because that's how we use the cookie sync info.
// We also must allow all origins because every site on the internet _could_ call us.
//
// This is an inherent security risk. However, PBS doesn't use cookies for authorization--just identification.
// We only store the User's ID for each Bidder, and each Bidder has already exposed a public cookie sync endpoint
// which returns that data anyway.
//
// For more info, see:
//
// - https://github.com/rs/cors/issues/55
// - https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors/CORSNotSupportingCredentials
// - https://portswigger.net/blog/exploiting-cors-misconfigurations-for-bitcoins-and-bounties
c := cors.New(cors.Options{
AllowCredentials: true,
AllowOriginFunc: func(origin string) bool {
return true
},
AllowedHeaders: []string{"Origin", "X-Requested-With", "Content-Type", "Accept"}})
corsRouter := c.Handler(router)
corsRouter := supportCORS(router)

// Add no cache headers
noCacheHandler := NoCache{corsRouter}
Expand All @@ -779,3 +758,28 @@ func serve(revision string, cfg *config.Configuration) error {
server.Listen(cfg, noCacheHandler, adminRouter, metricsEngine)
return nil
}

// Fixes #648
//
// These CORS options pose a security risk... but it's a calculated one.
// People _must_ call us with "withCredentials" set to "true" because that's how we use the cookie sync info.
// We also must allow all origins because every site on the internet _could_ call us.
//
// This is an inherent security risk. However, PBS doesn't use cookies for authorization--just identification.
// We only store the User's ID for each Bidder, and each Bidder has already exposed a public cookie sync endpoint
// which returns that data anyway.
//
// For more info, see:
//
// - https://github.com/rs/cors/issues/55
// - https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors/CORSNotSupportingCredentials
// - https://portswigger.net/blog/exploiting-cors-misconfigurations-for-bitcoins-and-bounties
func supportCORS(handler http.Handler) http.Handler {
c := cors.New(cors.Options{
AllowCredentials: true,
AllowOriginFunc: func(origin string) bool {
return true
},
AllowedHeaders: []string{"Origin", "X-Requested-With", "Content-Type", "Accept"}})
return c.Handler(handler)
}
19 changes: 19 additions & 0 deletions pbs_light_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (

"github.com/mxmCherry/openrtb"
"github.com/spf13/viper"
"github.com/stretchr/testify/assert"

"github.com/prebid/prebid-server/cache/dummycache"
"github.com/prebid/prebid-server/config"
Expand Down Expand Up @@ -688,6 +689,24 @@ func TestPanicRecovery(t *testing.T) {
recovered(nil, pbsmetrics.AdapterLabels{})
}

// Prevents #648
func TestCORSSupport(t *testing.T) {
const origin = "https://publisher-domain.com"
handler := func(w http.ResponseWriter, r *http.Request) {}
cors := supportCORS(http.HandlerFunc(handler))
rr := httptest.NewRecorder()
req, err := http.NewRequest("OPTIONS", "http://some-domain.com/openrtb2/auction", nil)
req.Header.Set("Access-Control-Request-Method", "POST")
req.Header.Set("Access-Control-Request-Headers", "origin")
req.Header.Set("Origin", origin)

if !assert.NoError(t, err) {
return
}
cors.ServeHTTP(rr, req)
assert.Equal(t, origin, rr.Header().Get("Access-Control-Allow-Origin"))
}

func compareStrings(t *testing.T, message string, expect string, actual string) {
if expect != actual {
t.Errorf(message, expect, actual)
Expand Down

0 comments on commit 80891c0

Please sign in to comment.