1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-09-27 04:03:00 +02:00

support Authorization token protection in bw serve

This commit is contained in:
Simon Merschjohann 2024-04-26 19:39:52 +00:00
parent b482a15d34
commit f98a180dfb
2 changed files with 43 additions and 0 deletions

View File

@ -32,6 +32,7 @@ import { GetCommand } from "./get.command";
import { ListCommand } from "./list.command"; import { ListCommand } from "./list.command";
import { RestoreCommand } from "./restore.command"; import { RestoreCommand } from "./restore.command";
import { StatusCommand } from "./status.command"; import { StatusCommand } from "./status.command";
import { readFileSync, existsSync } from "fs";
export class ServeCommand { export class ServeCommand {
private listCommand: ListCommand; private listCommand: ListCommand;
@ -183,6 +184,29 @@ export class ServeCommand {
process.env.BW_SERVE = "true"; process.env.BW_SERVE = "true";
process.env.BW_NOINTERACTION = "true"; process.env.BW_NOINTERACTION = "true";
const authTokenEnabled = !options.disableAuth;
var useToken = null;
if(options.authToken != null && options.authToken.length > 0) {
useToken = options.authToken;
}
if(options.authTokenFile != null && options.authTokenFile.length > 0) {
if(!existsSync(options.authTokenFile)) {
this.main.logService.error("Auth token file does not exist.");
return;
}
useToken = readFileSync(options.authTokenFile, 'utf8').trim();
}
if(options.authTokenEnv != null && options.authTokenEnv.length > 0) {
useToken = process.env[options.authTokenEnv];
}
const authToken = useToken || process.env.BW_SERVE_AUTH_TOKEN;
if(authTokenEnabled && (authToken == null || authToken.length == 0)) {
this.main.logService.error("No auth token provided. Please deactivate auth explicitly or provide an auth token using --auth-token, --auth-token-file, --auth-token-env or BW_SERVE_AUTH_TOKEN environment variable.");
return;
}
server server
.use(async (ctx, next) => { .use(async (ctx, next) => {
if (protectOrigin && ctx.headers.origin != undefined) { if (protectOrigin && ctx.headers.origin != undefined) {
@ -198,6 +222,21 @@ export class ServeCommand {
} }
await next(); await next();
}) })
.use(async (ctx, next) => {
if(!authTokenEnabled) {
await next();
return;
}
if (ctx.request.headers.authorization == null || ctx.request.headers.authorization.indexOf("Bearer " + authToken) != 0) {
ctx.status = 403;
this.main.logService.warning(
`Blocking request from as token is invalid or missing.`,
);
return;
}
await next();
})
.use(koaBodyParser()) .use(koaBodyParser())
.use(koaJson({ pretty: false, param: "pretty" })); .use(koaJson({ pretty: false, param: "pretty" }));

View File

@ -479,6 +479,10 @@ export class Program {
.description("Start a RESTful API webserver.") .description("Start a RESTful API webserver.")
.option("--hostname <hostname>", "The hostname to bind your API webserver to.") .option("--hostname <hostname>", "The hostname to bind your API webserver to.")
.option("--port <port>", "The port to run your API webserver on.") .option("--port <port>", "The port to run your API webserver on.")
.option("--auth-token-env <authTokenEnv>", "The environment variable to use for the auth token. Defaults to BW_SERVE_AUTH_TOKEN if not set.")
.option("--auth-token-file <authTokenFile>", "The file to use for the auth token.")
.option("--auth-token <authToken>", "The auth token to use for authentication.")
.option("--disable-auth", "If set, disables authentication.")
.option( .option(
"--disable-origin-protection", "--disable-origin-protection",
"If set, allows requests with origin header. Warning, this option exists for backwards compatibility reasons and exposes your environment to known CSRF attacks.", "If set, allows requests with origin header. Warning, this option exists for backwards compatibility reasons and exposes your environment to known CSRF attacks.",