Archived
1
0

Fix relative paths (#4594)

* Add tests for relativeRoot

* Remove path.posix.join

Since this is for file system paths it feels incorrect to use it on
URL paths as they are different in many ways.

* Rewrite cookie path logic

Before we relied on the client to resolve the base given to it by the
backend against the path.

Instead have the client pass that information along so we can resolve it
on the backend.  This means the client has to do less work.

* Do not remove out directory before watch

This is re-used for incremental compilation.

Also remove del since that was the only use (and we can use fs.rmdir in
the future if we need something like this).

* Remove unused function resolveBase
This commit is contained in:
Asher
2021-12-08 15:52:15 -06:00
committed by GitHub
parent 9d9f3a41ab
commit 4b4ec37880
14 changed files with 91 additions and 153 deletions

View File

@ -5,7 +5,7 @@ import * as os from "os"
import * as path from "path"
import { CookieKeys } from "../../common/http"
import { rootPath } from "../constants"
import { authenticated, getCookieDomain, redirect, replaceTemplates } from "../http"
import { authenticated, getCookieOptions, redirect, replaceTemplates } from "../http"
import { getPasswordMethod, handlePasswordValidation, humanPath, sanitizeString, escapeHtml } from "../util"
// RateLimiter wraps around the limiter library for logins.
@ -84,15 +84,7 @@ router.post<{}, string, { password: string; base?: string }, { to?: string }>("/
if (isPasswordValid) {
// The hash does not add any actual security but we do it for
// obfuscation purposes (and as a side effect it handles escaping).
res.cookie(CookieKeys.Session, hashedPassword, {
domain: getCookieDomain(req.headers.host || "", req.args["proxy-domain"]),
// Browsers do not appear to allow cookies to be set relatively so we
// need to get the root path from the browser since the proxy rewrites
// it out of the path. Otherwise code-server instances hosted on
// separate sub-paths will clobber each other.
path: req.body.base ? path.posix.join(req.body.base, "..", "/") : "/",
sameSite: "lax",
})
res.cookie(CookieKeys.Session, hashedPassword, getCookieOptions(req))
const to = (typeof req.query.to === "string" && req.query.to) || "/"
return redirect(req, res, to, { to: undefined })

View File

@ -1,21 +1,14 @@
import { Router } from "express"
import { CookieKeys } from "../../common/http"
import { getCookieDomain, redirect } from "../http"
import { getCookieOptions, redirect } from "../http"
import { sanitizeString } from "../util"
export const router = Router()
router.get<{}, undefined, undefined, { base?: string; to?: string }>("/", async (req, res) => {
const path = sanitizeString(req.query.base) || "/"
const to = sanitizeString(req.query.to) || "/"
// Must use the *identical* properties used to set the cookie.
res.clearCookie(CookieKeys.Session, {
domain: getCookieDomain(req.headers.host || "", req.args["proxy-domain"]),
path: decodeURIComponent(path),
sameSite: "lax",
})
res.clearCookie(CookieKeys.Session, getCookieOptions(req))
return redirect(req, res, to, { to: undefined, base: undefined })
const to = sanitizeString(req.query.to) || "/"
return redirect(req, res, to, { to: undefined, base: undefined, href: undefined })
})

View File

@ -24,7 +24,7 @@ export class CodeServerRouteWrapper {
const isAuthenticated = await authenticated(req)
if (!isAuthenticated) {
return redirect(req, res, "login/", {
return redirect(req, res, "login", {
// req.baseUrl can be blank if already at the root.
to: req.baseUrl && req.baseUrl !== "/" ? req.baseUrl : undefined,
})