Set-Cookie Manipulation in reverse_proxy

1. My Caddy version (caddy version):

v2.0.0-rc.3

2. How I run Caddy:

I was setting up a reverse proxy for my favourite game canto.world-of-dungeons.org as some of my friends complained about the bad server connection. So I set up a simple Caddy reverse proxy on my VPS with domain name canto.wannaexpresso.com, but after I logged in I couldn’t do anything as the game alerts ‘please enable cookie’.

I thought the problem was with set-cookie after I read an article on nginx reverse proxy which suggested sending and receiving Set-Cookie with the correct domain, that is, sending original domain set-cookie to canto.world-of-dungeons.org and returning canto.wannaexpresso.com set-cookie to browser.

So I tried setting header_up in Caddyfile with replacements, but the set-cookie turned from

world=CC; expires=Sat, 01-Aug-2020 01:11:00 GMT; path=/; domain=world-of-dungeons.org

to

wannaexpresso.comwwannaexpresso.comowannaexpresso.comrwannaexpresso.comlwannaexpresso.comdwannaexpresso.com=wannaexpresso.comCwannaexpresso.comCwannaexpresso.com;wannaexpresso.com wannaexpresso.comewannaexpresso.comxwannaexpresso.compwannaexpresso.comiwannaexpresso.comrwannaexpresso.comewannaexpresso.comswannaexpresso.com=wannaexpresso.comSwannaexpresso.comawannaexpresso.comtwannaexpresso.com,wannaexpresso.com wannaexpresso.com0wannaexpresso.com1wannaexpresso.com-wannaexpresso.comAwannaexpresso.comuwannaexpresso.comgwannaexpresso.com-wannaexpresso.com2wannaexpresso.com0wannaexpresso.com2wannaexpresso.com0wannaexpresso.com wannaexpresso.com0wannaexpresso.com1wannaexpresso.com:wannaexpresso.com1wannaexpresso.com1wannaexpresso.com:wannaexpresso.com0wannaexpresso.com0wannaexpresso.com wannaexpresso.comGwannaexpresso.comMwannaexpresso.comTwannaexpresso.com;wannaexpresso.com wannaexpresso.compwannaexpresso.comawannaexpresso.comtwannaexpresso.comhwannaexpresso.com=wannaexpresso.com/wannaexpresso.com;wannaexpresso.com wannaexpresso.comdwannaexpresso.comowannaexpresso.commwannaexpresso.comawannaexpresso.comiwannaexpresso.comnwannaexpresso.com=wannaexpresso.comwwannaexpresso.comowannaexpresso.comrwannaexpresso.comlwannaexpresso.comdwannaexpresso.com-wannaexpresso.comowannaexpresso.comfwannaexpresso.com-wannaexpresso.comdwannaexpresso.comuwannaexpresso.comnwannaexpresso.comgwannaexpresso.comewannaexpresso.comowannaexpresso.comnwannaexpresso.comswannaexpresso.com.wannaexpresso.comowannaexpresso.comrwannaexpresso.comgwannaexpresso.com

I think I probably need a fix on the replacement statements. Please help me orz…

a. System environment:

Debian 10

b. Command:

caddy run

c. My complete Caddyfile or JSON config:

# My Caddyfile
canto.wannaexpresso.com {
  encode gzip
  reverse_proxy * http://canto.world-of-dungeons.org {
    header_up Host canto.world-of-dungeons.org
    header_up Set-Cookie wannaexpresso.com world-of-dungeons.org
    header_down Set-Cookie world-of-dungeons.org wannaexpresso.com
  }
}
1 Like

Haha, woooahh nellie. Lemme take a look at that. I’ll get back to you.

Edit: Yep, I can reproduce it:

curl -v "http://localhost:1111"
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 1111 (#0)
> GET / HTTP/1.1
> Host: localhost:1111
> User-Agent: curl/7.64.1
> Accept: */*
> 
< HTTP/1.1 200 OK
< Content-Length: 21
< Date: Thu, 23 Apr 2020 01:40:48 GMT
< Server: Caddy
< Server: Caddy
< Set-Cookie: wannaexpresso.comwwannaexpresso.comowannaexpresso.comrwannaexpresso.comlwannaexpresso.comdwannaexpresso.com=wannaexpresso.comCwannaexpresso.comCwannaexpresso.com;wannaexpresso.com wannaexpresso.comewannaexpresso.comxwannaexpresso.compwannaexpresso.comiwannaexpresso.comrwannaexpresso.comewannaexpresso.comswannaexpresso.com=wannaexpresso.comSwannaexpresso.comawannaexpresso.comtwannaexpresso.com,wannaexpresso.com wannaexpresso.com0wannaexpresso.com1wannaexpresso.com-wannaexpresso.comAwannaexpresso.comuwannaexpresso.comgwannaexpresso.com-wannaexpresso.com2wannaexpresso.com0wannaexpresso.com2wannaexpresso.com0wannaexpresso.com wannaexpresso.com0wannaexpresso.com1wannaexpresso.com:wannaexpresso.com1wannaexpresso.com1wannaexpresso.com:wannaexpresso.com0wannaexpresso.com0wannaexpresso.com wannaexpresso.comGwannaexpresso.comMwannaexpresso.comTwannaexpresso.com;wannaexpresso.com wannaexpresso.compwannaexpresso.comawannaexpresso.comtwannaexpresso.comhwannaexpresso.com=wannaexpresso.com/wannaexpresso.com;wannaexpresso.com wannaexpresso.comdwannaexpresso.comowannaexpresso.commwannaexpresso.comawannaexpresso.comiwannaexpresso.comnwannaexpresso.com=wannaexpresso.comwwannaexpresso.comowannaexpresso.comrwannaexpresso.comlwannaexpresso.comdwannaexpresso.com-wannaexpresso.comowannaexpresso.comfwannaexpresso.com-wannaexpresso.comdwannaexpresso.comuwannaexpresso.comnwannaexpresso.comgwannaexpresso.comewannaexpresso.comowannaexpresso.comnwannaexpresso.comswannaexpresso.com.wannaexpresso.comowannaexpresso.comrwannaexpresso.comgwannaexpresso.com
< Content-Type: text/plain; charset=utf-8

Fun

Ha! I know you’ve been checking on me! Thanks matt!

1 Like

Update: It works properly if you use header Set-Cookie world-of-dungeons.org wannaexpresso.com outside of your reverse_proxy directive. This should be pretty easy to fix, I think…

Alrighty, fixed in https://github.com/caddyserver/caddy/commit/1b061815b2a336ce4f8d1d3ce3054dab19e00745. Could you try that out, @Peter_Zhang? (Build artifacts will be available at that commit shortly.)

I’m still getting bad cookies with header Set-Cookie.

canto.wannaexpresso.com {
  encode gzip
  header Set-Cookie world-of-dungeons.org wannaexpresso.com
  reverse_proxy * http://canto.world-of-dungeons.org {
    header_up Host canto.world-of-dungeons.org
  }
}

And do you mean I could build on your latest commit to get it fixed? Thankkks a lot matt!

1 Like

Can you elaborate?

Yes - the CI server compiles Caddy for you at each commit so you could just download that if you want.

1 Like

On the page right after I login (which is / I believe), the original site headers are like

Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html
Date: Thu, 23 Apr 2020 02:08:12 GMT
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Keep-Alive: timeout=5, max=200
Pragma: no-cache
Server: Apache/2.2.22 (Debian)
Set-Cookie: world=CC; expires=Sat, 01-Aug-2020 02:08:12 GMT; path=/; domain=world-of-dungeons.org
Set-Cookie: plain=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/; domain=world-of-dungeons.org
Set-Cookie: warn_email=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/; domain=world-of-dungeons.org
Transfer-Encoding: chunked
Vary: Accept-Encoding
X-DNS-Prefetch-Control: off
X-Powered-By: PHP/5.4.45-0+deb7u14
X-XSS-Protection: 0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en-GB;q=0.8,en;q=0.7
Connection: keep-alive
Cookie: savepass=1; system=a5HJ4gkO0SH4xFmuSxsWH8PTeQ5xXfWx; world=CC; 42834fb68c786f736988cc445ffdc7ba=255c595bc5b02c7295975064fe2e3c8f; login_CC=gsr9l8l7t68nlggog94qo948bcvzlw02; PHPSESSID=bc56u3yqc6oc01efq317c2je9vx72wl7
DNT: 1
Host: canto.world-of-dungeons.org
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36

And on my proxy site it looks like this

cache-control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
content-encoding: gzip
content-type: text/html
date: Thu, 23 Apr 2020 02:08:31 GMT
expires: Thu, 19 Nov 1981 08:52:00 GMT
pragma: no-cache
server: Caddy
server: Apache/2.2.22 (Debian)
set-cookie: world=CC; expires=Sat, 01-Aug-2020 02:08:31 GMT; path=/; domain=world-of-dungeons.org
set-cookie: plain=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/; domain=world-of-dungeons.org
set-cookie: savepass=1; expires=Wed, 22-Jul-2020 02:08:31 GMT; path=/; domain=world-of-dungeons.org
set-cookie: PHPSESSID=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/
set-cookie: warn_email=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/; domain=world-of-dungeons.org
set-cookie: system=Osz4IjRpwIsppReJTkG1dynIHsWWuIR6; expires=Wed, 22-Jul-2020 02:08:31 GMT; path=/; domain=world-of-dungeons.org
set-cookie: a0adc13c13ed6ad66308b620adb64275=255c595bc5b02c7295975064fe2e3c8f; expires=Thu, 23-Apr-2020 03:08:31 GMT; path=/; domain=world-of-dungeons.org
set-cookie: login_CC=9invao8byjhrz0ui3iq8gjsmaaukq7fz; expires=Wed, 22-Jul-2020 02:08:31 GMT; path=/; domain=world-of-dungeons.org
set-cookie: world=CC; expires=Wed, 22-Jul-2020 02:08:31 GMT; path=/; domain=world-of-dungeons.org
status: 200
vary: Accept-Encoding
X-DNS-Prefetch-Control: off
x-powered-by: PHP/5.4.45-0+deb7u14
x-xss-protection: 0
:authority: canto.wannaexpresso.com
:method: POST
:path: /
:scheme: https
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
accept-encoding: gzip, deflate, br
accept-language: zh-CN,zh;q=0.9,en-GB;q=0.8,en;q=0.7
cache-control: max-age=0
content-length: 95
content-type: application/x-www-form-urlencoded
cookie: PHPSESSID=ixqns55rbcp5mg7z2lztrfciak0dtvg7
dnt: 1
origin: https://canto.wannaexpresso.com
referer: https://canto.wannaexpresso.com/
sec-fetch-dest: document
sec-fetch-mode: navigate
sec-fetch-site: same-origin
sec-fetch-user: ?1
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36

And after I login onto my proxy site, any further operation would lead to a game error page warning “browser does not support cookie or cookie disabled”.

When I click into the same link on both sites after login , I checked again the headers, it seemed that some of the cookies are missing:

The original site header contains

# Correct Page on Original Site
Cookie: savepass=1; system=a5HJ4gkO0SH4xFmuSxsWH8PTeQ5xXfWx; world=CC; 42834fb68c786f736988cc445ffdc7ba=255c595bc5b02c7295975064fe2e3c8f; login_CC=gsr9l8l7t68nlggog94qo948bcvzlw02; PHPSESSID=bc56u3yqc6oc01efq317c2je9vx72wl7

But my proxy site cookie only had

# Error Page on Proxy Site
Cookie: PHPSESSID=nfq7gj0j560a0zzlei3zhkp5yquhve73

Is that using the latest patch from a few minutes ago, with your original Caddyfile? (i.e. header_down not header directive)?

1 Like

That’s with original caddy rc2 and header set-cookie

Okay – that’s an old version, and is broken. Run from the latest commit on master, and use your original Caddyfile and see how it goes.

2 Likes

Got it, working on building!

You can grab the CI artifacts from here if you want to avoid building

2 Likes

OMG that’s even more awesome! Wish I had known that!

My VPS couldn’t build because of the 512M memory so I built on my laptop and uploaded.

And it worked! Now the set-cookies are correctly set to domain=wannaexpresso.com.

I’m using caddy version (devel) and Caddyfile as follows:

canto.wannaexpresso.com {
  encode gzip
  reverse_proxy * http://canto.world-of-dungeons.org {
    header_up Host canto.world-of-dungeons.org
    header_down Set-Cookie world-of-dungeons.org wannaexpresso.com
  }
}

Thanks heavenly matt!

3 Likes

Great, glad to hear it!

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.