mirror of
https://github.com/coder/code-server.git
synced 2026-05-05 03:55:18 +02:00
feat: add wildcard support to trusted-origins (#7697)
This commit is contained in:
committed by
GitHub
parent
d544846caa
commit
4d615f18a9
@@ -351,6 +351,25 @@ export function ensureOrigin(req: express.Request, _?: express.Response, next?:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if the origin matches any trusted origin. Entries are matched
|
||||||
|
* as exact strings, the special wildcard `"*"`, or `*.example.com`-style
|
||||||
|
* domain wildcards (same as --proxy-domain).
|
||||||
|
*/
|
||||||
|
export function isTrustedOrigin(origin: string, trustedOrigins: string[]): boolean {
|
||||||
|
return trustedOrigins.some((trusted) => {
|
||||||
|
if (trusted === "*" || trusted === origin) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// *.example.com style: match origin if it is the domain or a subdomain
|
||||||
|
if (trusted.startsWith("*.")) {
|
||||||
|
const domain = trusted.slice(2).toLowerCase()
|
||||||
|
return origin === domain || origin.endsWith("." + domain)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Authenticate the request origin against the host. Throw if invalid.
|
* Authenticate the request origin against the host. Throw if invalid.
|
||||||
*/
|
*/
|
||||||
@@ -370,7 +389,7 @@ export function authenticateOrigin(req: express.Request): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const trustedOrigins = req.args["trusted-origins"] || []
|
const trustedOrigins = req.args["trusted-origins"] || []
|
||||||
if (trustedOrigins.includes(origin) || trustedOrigins.includes("*")) {
|
if (isTrustedOrigin(origin, trustedOrigins)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,30 @@ describe("http", () => {
|
|||||||
expect(http.relativeRoot("/foo/bar/")).toStrictEqual("./../..")
|
expect(http.relativeRoot("/foo/bar/")).toStrictEqual("./../..")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("isTrustedOrigin", () => {
|
||||||
|
it("should match exact origins", () => {
|
||||||
|
expect(http.isTrustedOrigin("localhost:8080", ["localhost:8080"])).toBe(true)
|
||||||
|
expect(http.isTrustedOrigin("example.com", ["example.com"])).toBe(true)
|
||||||
|
expect(http.isTrustedOrigin("example.com", ["other.com"])).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should match the wildcard *", () => {
|
||||||
|
expect(http.isTrustedOrigin("anything.example.com", ["*"])).toBe(true)
|
||||||
|
expect(http.isTrustedOrigin("localhost:8080", ["*"])).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should match *.example.com wildcard (same style as --proxy-domain)", () => {
|
||||||
|
expect(http.isTrustedOrigin("sub.example.com", ["*.example.com"])).toBe(true)
|
||||||
|
expect(http.isTrustedOrigin("example.com", ["*.example.com"])).toBe(true)
|
||||||
|
expect(http.isTrustedOrigin("evil.com", ["*.example.com"])).toBe(false)
|
||||||
|
expect(http.isTrustedOrigin("example.com.evil.com", ["*.example.com"])).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should return false for an empty trusted origins list", () => {
|
||||||
|
expect(http.isTrustedOrigin("example.com", [])).toBe(false)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe("origin", () => {
|
describe("origin", () => {
|
||||||
;[
|
;[
|
||||||
{
|
{
|
||||||
@@ -54,6 +78,22 @@ describe("http", () => {
|
|||||||
host: "localhost:8080",
|
host: "localhost:8080",
|
||||||
expected: "malformed", // Parsing fails completely.
|
expected: "malformed", // Parsing fails completely.
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
origin: "http://sub.example.com",
|
||||||
|
host: "other.com",
|
||||||
|
trustedOrigins: ["*.example.com"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
origin: "http://evil.com",
|
||||||
|
host: "other.com",
|
||||||
|
trustedOrigins: ["*.example.com"],
|
||||||
|
expected: "does not match",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
origin: "http://sub.example.com",
|
||||||
|
host: "other.com",
|
||||||
|
trustedOrigins: ["*"],
|
||||||
|
},
|
||||||
].forEach((test) => {
|
].forEach((test) => {
|
||||||
;[
|
;[
|
||||||
["host", test.host],
|
["host", test.host],
|
||||||
@@ -70,7 +110,9 @@ describe("http", () => {
|
|||||||
origin: test.origin,
|
origin: test.origin,
|
||||||
[key]: value,
|
[key]: value,
|
||||||
},
|
},
|
||||||
args: {},
|
args: {
|
||||||
|
"trusted-origins": (test as { trustedOrigins?: string[] }).trustedOrigins,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
if (typeof test.expected === "string") {
|
if (typeof test.expected === "string") {
|
||||||
expect(() => http.authenticateOrigin(req)).toThrow(test.expected)
|
expect(() => http.authenticateOrigin(req)).toThrow(test.expected)
|
||||||
|
|||||||
Reference in New Issue
Block a user