add check for x-requested-with header
This commit is contained in:
@@ -52,11 +52,15 @@ describe('GoogleAuthProvider', () => {
|
||||
});
|
||||
|
||||
describe('start authentication handler', () => {
|
||||
const mockResponse = ({} as unknown) as express.Response;
|
||||
const mockResponse = ({
|
||||
send: jest.fn().mockReturnThis(),
|
||||
status: jest.fn().mockReturnThis(),
|
||||
} as unknown) as express.Response;
|
||||
const mockNext: express.NextFunction = jest.fn();
|
||||
|
||||
it('should initiate authenticate request with provided scopes', () => {
|
||||
const mockRequest = ({
|
||||
header: () => 'XMLHttpRequest',
|
||||
query: {
|
||||
scope: 'a,b',
|
||||
},
|
||||
@@ -80,6 +84,7 @@ describe('GoogleAuthProvider', () => {
|
||||
|
||||
it('should throw error if no scopes provided', () => {
|
||||
const mockRequest = ({
|
||||
header: () => 'XMLHttpRequest',
|
||||
query: {},
|
||||
} as unknown) as express.Request;
|
||||
|
||||
@@ -93,7 +98,9 @@ describe('GoogleAuthProvider', () => {
|
||||
});
|
||||
|
||||
describe('logout handler', () => {
|
||||
const mockRequest = ({} as unknown) as express.Request;
|
||||
const mockRequest = ({
|
||||
header: () => 'XMLHttpRequest',
|
||||
} as unknown) as express.Request;
|
||||
|
||||
it('should perform logout and respond with 200', () => {
|
||||
const mockResponse: any = ({
|
||||
@@ -122,7 +129,9 @@ describe('GoogleAuthProvider', () => {
|
||||
});
|
||||
|
||||
describe('redirect frame handler', () => {
|
||||
const mockRequest = ({} as unknown) as express.Request;
|
||||
const mockRequest = ({
|
||||
header: () => 'XMLHttpRequest',
|
||||
} as unknown) as express.Request;
|
||||
const mockResponse: any = ({
|
||||
status: jest.fn().mockReturnThis(),
|
||||
send: jest.fn().mockReturnThis(),
|
||||
@@ -245,6 +254,7 @@ describe('GoogleAuthProvider', () => {
|
||||
it('should respond with a 401', () => {
|
||||
const mockRequest = ({
|
||||
cookies: jest.fn(),
|
||||
header: () => 'XMLHttpRequest',
|
||||
} as unknown) as express.Request;
|
||||
|
||||
const googleAuthProvider = new GoogleAuthProvider(
|
||||
@@ -262,6 +272,7 @@ describe('GoogleAuthProvider', () => {
|
||||
|
||||
describe('refresh token cookie, no scope', () => {
|
||||
const mockRequest = ({
|
||||
header: () => 'XMLHttpRequest',
|
||||
cookies: { 'google-refresh-token': 'REFRESH_TOKEN' },
|
||||
query: {},
|
||||
} as unknown) as express.Request;
|
||||
@@ -349,6 +360,7 @@ describe('GoogleAuthProvider', () => {
|
||||
|
||||
describe('refresh token cookie and scope', () => {
|
||||
const mockRequest = ({
|
||||
header: () => 'XMLHttpRequest',
|
||||
cookies: { 'google-refresh-token': 'REFRESH_TOKEN' },
|
||||
query: {
|
||||
scope: 'a,b',
|
||||
@@ -387,6 +399,20 @@ describe('GoogleAuthProvider', () => {
|
||||
scope: 'a,b',
|
||||
});
|
||||
});
|
||||
|
||||
it('ensures x-requested-with header', () => {
|
||||
const mockHeaderRequest = ({
|
||||
header: () => 'TEST',
|
||||
} as unknown) as express.Request;
|
||||
|
||||
googleAuthProvider.refresh(mockHeaderRequest, mockResponse);
|
||||
expect(mockResponse.send).toBeCalledTimes(1);
|
||||
expect(mockResponse.send).toBeCalledWith(
|
||||
'Invalid X-Requested-With header',
|
||||
);
|
||||
expect(mockResponse.status).toBeCalledTimes(1);
|
||||
expect(mockResponse.status).toBeCalledWith(401);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -23,7 +23,7 @@ import {
|
||||
AuthProviderRouteHandlers,
|
||||
AuthProviderConfig,
|
||||
} from './../types';
|
||||
import { postMessageResponse } from './../utils';
|
||||
import { postMessageResponse, ensuresXRequestedWith } from './../utils';
|
||||
import { InputError } from '@backstage/backend-common';
|
||||
|
||||
export const THOUSAND_DAYS_MS = 1000 * 24 * 60 * 60 * 1000;
|
||||
@@ -95,7 +95,11 @@ export class GoogleAuthProvider
|
||||
})(req, res, next);
|
||||
}
|
||||
|
||||
async logout(_req: express.Request, res: express.Response) {
|
||||
async logout(req: express.Request, res: express.Response) {
|
||||
if (!ensuresXRequestedWith(req)) {
|
||||
return res.status(401).send('Invalid X-Requested-With header');
|
||||
}
|
||||
|
||||
const options: CookieOptions = {
|
||||
maxAge: 0,
|
||||
secure: false,
|
||||
@@ -110,6 +114,10 @@ export class GoogleAuthProvider
|
||||
}
|
||||
|
||||
async refresh(req: express.Request, res: express.Response) {
|
||||
if (!ensuresXRequestedWith(req)) {
|
||||
return res.status(401).send('Invalid X-Requested-With header');
|
||||
}
|
||||
|
||||
const refreshToken =
|
||||
req.cookies[`${this.providerConfig.provider}-refresh-token`];
|
||||
|
||||
|
||||
@@ -39,3 +39,12 @@ export const postMessageResponse = (
|
||||
</html>
|
||||
`);
|
||||
};
|
||||
|
||||
export const ensuresXRequestedWith = (req: express.Request) => {
|
||||
const requiredHeader = req.header('X-Requested-With');
|
||||
|
||||
if (!requiredHeader || requiredHeader !== 'XMLHttpRequest') {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user