Skip to content

Commit

Permalink
Security: can set array of auth tokens (#417)
Browse files Browse the repository at this point in the history
* Security: can set array of auth tokens

* Update src/config.ts

Co-authored-by: Selene <[email protected]>

---------

Co-authored-by: Selene <[email protected]>
  • Loading branch information
AgnesToulet and spinillos authored Apr 17, 2023
1 parent d49faae commit d6741ee
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 15 deletions.
18 changes: 18 additions & 0 deletions scripts/clean_target.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/bash

ARCH="${1:-}"
OUT="${2:-}"

if [ -z "$ARCH" ]; then
echo "ARCH (arg 1) has to be set"
exit 1
fi

PLUGIN_NAME=plugin-${ARCH}

if [ ! -z "$OUT" ]; then
PLUGIN_NAME=${OUT}
fi

rm -rf .dist/${PLUGIN_NAME}
rm -f ./artifacts/${PLUGIN_NAME}.zip
3 changes: 2 additions & 1 deletion src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ function populateServiceConfigFromEnv(config: ServiceConfig, env: NodeJS.Process
}

if (env['AUTH_TOKEN']) {
config.service.security.authToken = env['AUTH_TOKEN'];
const authToken = env['AUTH_TOKEN'] as string;
config.service.security.authToken = authToken.includes(' ') ? authToken.split(' ') : authToken;
}

if (env['LOG_LEVEL']) {
Expand Down
11 changes: 10 additions & 1 deletion src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export interface LoggingConfig {
}

export interface SecurityConfig {
authToken: string;
authToken: string | string[];
}

export interface ServiceConfig {
Expand Down Expand Up @@ -148,3 +148,12 @@ export const readJSONFileSync = (filePath: string): any => {
const rawdata = fs.readFileSync(filePath, 'utf8');
return JSON.parse(rawdata);
};

export const isAuthTokenValid = (config: SecurityConfig, reqAuthToken: string): boolean => {
let configToken = config.authToken || [''];
if (typeof configToken === "string") {
configToken = [configToken]
}

return reqAuthToken !== "" && configToken.includes(reqAuthToken)
}
16 changes: 7 additions & 9 deletions src/plugin/v2/grpc_plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as protoLoader from '@grpc/proto-loader';
import * as promClient from 'prom-client';
import { GrpcPlugin } from '../../node-plugin';
import { Logger } from '../../logger';
import { PluginConfig, SecurityConfig } from '../../config';
import { PluginConfig, SecurityConfig, isAuthTokenValid } from '../../config';
import { createBrowser, Browser } from '../../browser';
import { HTTPHeaders, ImageRenderOptions, RenderOptions } from '../../types';
import {
Expand Down Expand Up @@ -93,7 +93,7 @@ export class RenderGRPCPluginV2 implements GrpcPlugin {
class PluginGRPCServer {
private browserVersion: string | undefined;

constructor(private browser: Browser, private log: Logger, private sanitizer: Sanitizer, private securityCfg: SecurityConfig) {}
constructor(private browser: Browser, private log: Logger, private sanitizer: Sanitizer, private securityCfg: SecurityConfig) { }

async start(browserVersion?: string) {
this.browserVersion = browserVersion;
Expand All @@ -108,8 +108,7 @@ class PluginGRPCServer {
return callback({ code: Status.INVALID_ARGUMENT, details: 'Request cannot be null' });
}

const configToken = this.securityCfg.authToken || '';
if (!req.authToken || req.authToken !== configToken) {
if (!isAuthTokenValid(this.securityCfg, req.authToken)) {
return callback({ code: Status.UNAUTHENTICATED, details: 'Unauthorized request' });
}

Expand Down Expand Up @@ -158,8 +157,7 @@ class PluginGRPCServer {
return callback({ code: Status.INVALID_ARGUMENT, details: 'Request cannot be null' });
}

const configToken = this.securityCfg.authToken || '';
if (!req.authToken || req.authToken !== configToken) {
if (!isAuthTokenValid(this.securityCfg, req.authToken)) {
return callback({ code: Status.UNAUTHENTICATED, details: 'Unauthorized request' });
}

Expand Down Expand Up @@ -217,8 +215,7 @@ class PluginGRPCServer {
async sanitize(call: grpc.ServerUnaryCall<GRPCSanitizeRequest, any>, callback: grpc.sendUnaryData<GRPCSanitizeResponse>) {
const grpcReq = call.request;

const configToken = this.securityCfg.authToken || '';
if (!grpcReq.authToken || grpcReq.authToken !== configToken) {
if (!isAuthTokenValid(this.securityCfg, grpcReq.authToken)) {
return callback({ code: Status.UNAUTHENTICATED, details: 'Unauthorized request' });
}

Expand Down Expand Up @@ -324,7 +321,8 @@ const populateConfigFromEnv = (config: PluginConfig) => {
}

if (env['GF_PLUGIN_AUTH_TOKEN']) {
config.plugin.security.authToken = env['GF_PLUGIN_AUTH_TOKEN'];
const authToken = env['GF_PLUGIN_AUTH_TOKEN'] as string;
config.plugin.security.authToken = authToken.includes(' ') ? authToken.split(' ') : authToken;
}
};

Expand Down
6 changes: 2 additions & 4 deletions src/service/middlewares.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import express = require('express');
import * as boom from '@hapi/boom';
import { ImageRenderOptions } from '../types';
import { SecurityConfig } from '../config';
import { SecurityConfig, isAuthTokenValid } from '../config';

export const asyncMiddleware = (fn) => (req, res, next) => {
Promise.resolve(fn(req, res, next)).catch((err) => {
Expand All @@ -28,10 +28,8 @@ export const trustedUrlMiddleware = (

export const authTokenMiddleware = (config: SecurityConfig) => {
return (req: express.Request<any, any, any, ImageRenderOptions, any>, res: express.Response, next: express.NextFunction) => {
const cfgToken = config.authToken || '';
const headerToken = req.header('X-Auth-Token');

if (headerToken === undefined || headerToken !== cfgToken) {
if (headerToken === undefined || !isAuthTokenValid(config, headerToken)) {
return next(boom.unauthorized('Unauthorized request'));
}

Expand Down

0 comments on commit d6741ee

Please sign in to comment.