Horndev / zapread.com

Website for zapread.com
https://www.zapread.com
GNU Affero General Public License v3.0
19 stars 4 forks source link

WebSocket XSS during LNURL-auth flow if k1 is known to attacker i.e., can see the screen #838

Open wfinn opened 1 year ago

wfinn commented 1 year ago

Describe the bug This is a minor XSS issue which is only exploitable if "k1" of the lnurl-auth flow is known, which can happen e.g. in cases where attackers can record the victims screen and quickly conduct an attack.

To Reproduce

POST /api/auth/lnauthcb HTTP/2
Host: realtime.zapread.com
Content-Type: application/json
Content-Length: 125

{"toUserId":"PASTE_k1_HERE","Callback":"javascript:alert(1)//","Token":""}

Expected behavior Why is this realtime API accessible by me? Can it be changed, so only the zapread backend can use it?

Further, I recommend to hardcode the "callback" URL, to prevent abuse.
Please observe the following code snippet from https://github.com/Horndev/zapread.com/blob/a1ba83e4e72e718483821c1de33ae5e13b60d3e8/zapread.com/Scripts/src/realtime/auth/onlnauthlogin.js.

export function onlnauthlogin(callback, token) {
  // console.log("realtime callback: ", callback, token);
  appInsights.trackEvent({
    name: 'lnurl-auth login authenticated',
    properties: {
      pubkey: token
    }
  });
  appInsights.flush(); // send now

  // Go to callback with login
  window.location.replace(callback + "?code=" + token + "&state=" + state);
}

Note that callback which we can control in the call to realtime.zapread.com/api/auth/lnauthcb flows into the window.location.replace XSS sink.
If callback can not be hardcoded, I recommend to create a check that it matches ^/[a-zA-Z0-9].* so no protocols like https: or javascript: can be used, while also preventing the use of //foo. Screenshots image

Additional context I just want to be extra clear that this is a very low severity bug, as the QR code is usually not known, so this can not be mass exploited.

Horndev commented 1 year ago

Ok, I see the real issue. Sending the callback url over ws could be a weak spot. Easy to fix.

Horndev commented 1 year ago

I wrote a patch for this here: dbd7ca020eaa49cac8ec977c85ce1fa849cd6078

It will make it into the next release.

wfinn commented 1 year ago

lgtm but I still don't get why this realtime API is publicly accessible. Am I missing something?

Horndev commented 1 year ago

No you're not missing anything. I do need to implement cross-domain credential sharing to properly authenticate on the realtime API since it runs on a different service. Some things I do want to be public and others not. My vision was to have a public live activity stream at some point.