Skip to content

Commit

Permalink
Merge pull request #573 from companieshouse/IDVA5-1671-implementCSRFt…
Browse files Browse the repository at this point in the history
…oken

IDVA5-1671 implement csrf token
  • Loading branch information
sardhani-ch authored Jan 9, 2025
2 parents 15d9f57 + b21d319 commit c861a95
Show file tree
Hide file tree
Showing 50 changed files with 227 additions and 8 deletions.
11 changes: 10 additions & 1 deletion locales/cy/error-pages.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@

"technicalDifficuliesTitle": "Mae'n ddrwg gennym ein bod yn profi anawsterau technegol",
"technicalDifficuliesText1": "Ceisiwch eto mewn ychydig funudau.",
"technicalDifficuliesText2": "Os yw'r broblem hon yn parhau anfonwch e-bost i enquiries@companieshouse.gov.uk."
"technicalDifficuliesText2": "Os yw'r broblem hon yn parhau anfonwch e-bost i enquiries@companieshouse.gov.uk.",

"tryAgainLater": "Try again later welsh.",
"sorrySomethingWentWrong":"Sorry, something went wrong welsh",
"weHaveNotBeenAbleToSave":"We have not been able to save the information you submitted on the previous screen. This may be because the page was inactive for too long, or because of a technical issue. welsh",
"tryTheFollowing":"Try the following: welsh",
"useTheBackLink":"use the back link to return to the previous screen and resubmit the information welsh",
"signOutOfTheService":"sign out of the service, and then sign back in welsh",
"ifTheProblemContinues":"If the problem continues, welsh",
"contactUsLink":"contact us welsh",
"forHelp":"for help. welsh"
}
13 changes: 11 additions & 2 deletions locales/en/error-pages.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@

"technicalDifficuliesTitle": "Sorry we are experiencing technical difficulties",
"technicalDifficuliesText1": "Try again in a few moments.",
"technicalDifficuliesText2": "If this problem continues email enquiries@companieshouse.gov.uk."

"technicalDifficuliesText2": "If this problem continues email enquiries@companieshouse.gov.uk.",

"tryAgainLater": "Try again later.",
"sorrySomethingWentWrong":"Sorry, something went wrong",
"weHaveNotBeenAbleToSave":"We have not been able to save the information you submitted on the previous screen. This may be because the page was inactive for too long, or because of a technical issue.",
"tryTheFollowing":"Try the following:",
"useTheBackLink":"use the back link to return to the previous screen and resubmit the information",
"signOutOfTheService":"sign out of the service, and then sign back in",
"ifTheProblemContinues":"If the problem continues,",
"contactUsLink":"contact us",
"forHelp":"for help."
}
9 changes: 8 additions & 1 deletion src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import { v4 as uuidv4 } from "uuid";
import nocache from "nocache";
import { prepareCSPConfig } from "./middleware/content_security_policy_middleware_config";

import { csrfProtectionMiddleware } from "./middleware/csrf_protection_middleware";
import errorHandler from "../src/controllers/csrfErrorController";
const app = express();

const nonce: string = uuidv4();
Expand All @@ -37,7 +39,9 @@ const nunjucksEnv = nunjucks.configure([path.join(__dirname, "views"),
path.join(__dirname, "/../node_modules/govuk-frontend"),
path.join(__dirname, "/../../node_modules/govuk-frontend"),
path.join(__dirname, "/../node_modules/@companieshouse/ch-node-utils/templates"),
path.join(__dirname, "/../../node_modules/@companieshouse/ch-node-utils/templates")], {
path.join(__dirname, "/../../node_modules/@companieshouse/ch-node-utils/templates"),
path.join(__dirname, "/../node_modules/@companieshouse"),
path.join(__dirname, "/../../node_modules/@companieshouse")], {
autoescape: true,
express: app
});
Expand Down Expand Up @@ -68,6 +72,7 @@ app.use(cookieParser());
app.use(nocache());
app.use(helmet(prepareCSPConfig(nonce)));
app.use(`^(?!(${BASE_URL}${HEALTHCHECK}|${BASE_URL}$|${BASE_URL}${ACCESSIBILITY_STATEMENT}))*`, sessionMiddleware);
app.use(`^(?!(${BASE_URL}${HEALTHCHECK}|${BASE_URL}$|${BASE_URL}${ACCESSIBILITY_STATEMENT}))*`, csrfProtectionMiddleware);
app.use(`^(?!(${BASE_URL}${HEALTHCHECK}|${BASE_URL}$|${BASE_URL}${ACCESSIBILITY_STATEMENT})|(${BASE_URL}${SOLE_TRADER})|(${UPDATE_ACSP_DETAILS_BASE_URL}))*`, authenticationMiddleware);
app.use(`^(${BASE_URL}${SOLE_TRADER})*`, authenticationMiddlewareForSoleTrader);
app.use(commonTemplateVariablesMiddleware);
Expand All @@ -88,6 +93,8 @@ app.use((req: Request, res: Response, next: NextFunction) => {
// Channel all requests through router dispatch
routerDispatch(app);

app.use(...errorHandler);

// Unhandled errors
app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
logger.error(`${err.name} - appError: ${err.message} - ${err.stack}`);
Expand Down
1 change: 1 addition & 0 deletions src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export const SAVED_APPLICATION = `${BASE_COMMON_URL}/saved-application/saved-app
export const ERROR_400 = `${BASE_PARTIALS_URL}/error_400`;
export const ERROR_404 = `${BASE_PARTIALS_URL}/error_404`;
export const ERROR_500 = `${BASE_PARTIALS_URL}/error_500`;
export const ERROR_403 = `${BASE_PARTIALS_URL}/error_403`;

export const SELECT_AML_SUPERVISOR = `${BASE_COMMON_URL}/select-aml-supervisory-bodies/select-aml-supervisory-bodies`;
export const CHECK_YOUR_ANSWERS = `${BASE_COMMON_URL}/check-your-answers/check-your-answers`;
Expand Down
17 changes: 17 additions & 0 deletions src/controllers/csrfErrorController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { ErrorRequestHandler, NextFunction, Request, Response } from "express";
import { CsrfError } from "@companieshouse/web-security-node";
import { ErrorService } from "../services/errorService";
import { getLocalesService, selectLang } from "../utils/localise";
import logger from "../utils/logger";

export const csrfErrorHandler: ErrorRequestHandler = (err: any, req: Request, res: Response, next:NextFunction) => {
if (err instanceof CsrfError) {
logger.error(`${err.name} - appError: ${err.message} - ${err.stack}`);
const errorService = new ErrorService();
errorService.render403Page(res, getLocalesService(), selectLang(req.query.lang), req.url);
} else {
next(err);
}
};

export default [csrfErrorHandler];
9 changes: 9 additions & 0 deletions src/middleware/csrf_protection_middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { CsrfProtectionMiddleware } from "@companieshouse/web-security-node";
import { COOKIE_NAME } from "../utils/properties";
import { sessionStore } from "./session_middleware";

export const csrfProtectionMiddleware = CsrfProtectionMiddleware({
sessionStore,
enabled: true,
sessionCookieName: COOKIE_NAME
});
2 changes: 1 addition & 1 deletion src/middleware/session_middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Redis from "ioredis";
import { CACHE_SERVER, COOKIE_DOMAIN, COOKIE_NAME, COOKIE_SECRET, COOKIE_SECURE_ONLY, DEFAULT_SESSION_EXPIRATION } from "../utils/properties";

const redis = new Redis(CACHE_SERVER);
const sessionStore = new SessionStore(redis);
export const sessionStore = new SessionStore(redis);

export const sessionMiddleware = SessionMiddleware({
cookieDomain: COOKIE_DOMAIN,
Expand Down
8 changes: 8 additions & 0 deletions src/services/errorService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,12 @@ export class ErrorService {
currentUrl: req.url
});
}

public render403Page = (res:Response, locales:LocalesService, lang:string, currentUrl: string) => {
res.status(403).render(config.ERROR_403, {
title: "Sorry, something went wrong",
...getLocaleInfo(locales, lang),
currentUrl: currentUrl
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
{% endif %}

<form action="" method="POST">
{% include "partials/csrf_token.njk" %}
{% if businessName %}
{% include "partials/business_name.njk" %}
{% endif %}
Expand Down
1 change: 1 addition & 0 deletions src/views/common/aml-body-number/aml-body-number.njk
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
{% set title = i18n.amlMembershipTitle %}
{% block main_content %}
<form action="" method="post">
{% include "partials/csrf_token.njk" %}
<fieldset class="govuk-fieldset">
<legend class="govuk-fieldset__legend govuk-fieldset__legend--l">
{% if acspType === "SOLE_TRADER" %}
Expand Down
1 change: 1 addition & 0 deletions src/views/common/check-aml-details/check-aml-details.njk
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
{% block main_content %}

<form class="form" action="" method="post">
{% include "partials/csrf_token.njk" %}
{% if typeOfBusiness === "SOLE_TRADER" %}
{% include "partials/user_name.njk" %}
{% else %}
Expand Down
1 change: 1 addition & 0 deletions src/views/common/check-your-answers/check-your-answers.njk
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
{% set title = i18n.checkYourAnswersHeading %}
{% block main_content %}
<form method="post">
{% include "partials/csrf_token.njk" %}
<h1 class="govuk-heading-xl">{{ i18n.checkYourAnswersHeading }}</h1>
{% if typeOfBusiness === "SOLE_TRADER" %}
{% include "partials/check-your-answers/sole-trader-answers.njk" %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
{% set title = i18n.correspondenceAddressConfirmTitle %}
{% block main_content %}
<form class="form" action="" method="post">
{% include "partials/csrf_token.njk" %}
{% if businessName %}
{% include "partials/business_name.njk" %}
{% elif firstName %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
{% set title = i18n.correspondenceAddressManualTitle %}
{% block main_content %}
<form action="" method="POST">
{% include "partials/csrf_token.njk" %}
{% if businessName %}
{% include "partials/business_name.njk" %}
{% endif %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
{% set title = i18n.correspondenceLookUpAddressTitle %}
{% block main_content %}
<form action="" method="POST">
{% include "partials/csrf_token.njk" %}
{% if businessName %}
{% include "partials/business_name.njk" %}
{% elif firstName %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
{% endfor %}
{# Form section #}
<form action="" method="POST">
{% include "partials/csrf_token.njk" %}
{% if businessName %}
{% include "partials/business_name.njk" %}
{% endif %}
Expand Down
1 change: 1 addition & 0 deletions src/views/common/index/home.njk
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
{% set matomoPageTitle = i18n.startPageTitle %}
{% block main_content %}
<form action="" method="POST">
{% include "partials/csrf_token.njk" %}
<h1 class="govuk-heading-l">
{{ i18n.startPageTitle }}
</h1>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
{% set title = i18n.nameRegisteredWithAmlTitle %}
{% block main_content %}
<form action="" method="POST">
{% include "partials/csrf_token.njk" %}
{{ govukRadios({
errorMessage: errors.nameRegisteredWithAml if errors,
classes: "govuk-radios",
Expand Down
1 change: 1 addition & 0 deletions src/views/common/name/capture-name.njk
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
{% set title = i18n.whatIsYourNameTitle %}
{% block main_content %}
<form action="" method="POST">
{% include "partials/csrf_token.njk" %}
<div class="govuk-form-group">
<h1 class="govuk-heading-l">{{ i18n.whatIsYourNameTitle }}</h1>
{{ govukInput({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
{% set title = i18n.otherTypeOfBusinessTitle %}
{% block main_content %}
<form action="" method="POST">
{% include "partials/csrf_token.njk" %}
{% include "partials/user_name.njk" %}
<div class="govuk-form-group">
{{ govukRadios({
Expand Down
1 change: 1 addition & 0 deletions src/views/common/saved-application/saved-application.njk
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
{% set title = i18n.savedTitle %}
{% block main_content %}
<form action="" method="POST">
{% include "partials/csrf_token.njk" %}
{{ govukRadios({
errorMessage: errors.savedApplication if errors,
classes: "govuk-radios--inline",
Expand Down
1 change: 1 addition & 0 deletions src/views/common/sector-you-work-in/sector-you-work-in.njk
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
{% set title = i18n.sectorYouWorkInTitle %}
{% block main_content %}
<form action="" method="POST">
{% include "partials/csrf_token.njk" %}
{% if acspType == "SOLE_TRADER" %}
{% include "partials/user_name.njk" %}
{% endif %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
{% set title = i18n.selectAmlSupervisorTitle %}
{% block main_content %}
<form action="" method="POST">
{% include "partials/csrf_token.njk" %}
{% if acspType == "SOLE_TRADER" %}
{% include "partials/user_name.njk" %}
{% else %}
Expand Down
1 change: 1 addition & 0 deletions src/views/common/sign-out-page/sign-out.njk
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
{% set title = i18n.signoutTitle %}
{% block main_content %}
<form action="" method="POST">
{% include "partials/csrf_token.njk" %}
{{ govukRadios({
errorMessage: errors.signout if errors,
classes: "govuk-radios--inline",
Expand Down
1 change: 1 addition & 0 deletions src/views/common/type-of-business/type-of-business.njk
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
{% set title = i18n.typeOfBusinessTitle %}
{% block main_content %}
<form action="" method="POST">
{% include "partials/csrf_token.njk" %}
{% include "partials/user_name.njk" %}
{{ govukRadios({
errorMessage: errors.typeOfBusinessRadio if errors,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

{% set title = i18n.whatIsTheBusinessNameTitle %}
{% block main_content %}
<form action="" method="POST">
<form action="" method="POST">
{% include "partials/csrf_token.njk" %}
{{ govukInput({
label: {
text: i18n.whatIsTheBusinessNameTitle,
Expand Down
3 changes: 2 additions & 1 deletion src/views/common/what-is-your-email/what-is-your-email.njk
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

{% set title = i18n.whatIsYourEmailAddressTitle %}
{% block main_content %}
<form action="" method="POST">
<form action="" method="POST">
{% include "partials/csrf_token.njk" %}
{% set textHtml %}
{{ govukInput({
label: {
Expand Down
1 change: 1 addition & 0 deletions src/views/common/what-is-your-role/what-is-your-role.njk
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
{% set title = i18n.whatIsYourRoleTitle %}
{% block main_content %}
<form action="" method="POST">
{% include "partials/csrf_token.njk" %}
<div class="govuk-form-group">
{{ govukRadios({
errorMessage: errors.WhatIsYourRole if errors,
Expand Down
1 change: 1 addition & 0 deletions src/views/common/which-sector-other/which-sector-other.njk
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
{% set title = i18n.whichSectorOtherTitle %}
{% block main_content %}
<form action="" method="POST">
{% include "partials/csrf_token.njk" %}
{% if acspType == "SOLE_TRADER" %}
{% include "partials/user_name.njk" %}
{% endif %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

{% block main_content %}
<form method="post">
{% include "partials/csrf_token.njk" %}
{% if typeOfBusiness === "SOLE_TRADER" %}
{% include "partials/user_name.njk" %}
{% else %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
{% set title = i18n.amlInterruptTitle %}
{% block main_content %}
<form action="" method="POST">
{% include "partials/csrf_token.njk" %}
<h1 class="govuk-heading-l">{{ i18n.amlInterruptTitle }}</h1>
<p class="govuk-body">{{ i18n.text1 }}</p>
<p class="govuk-body">{{ i18n.text2 }}</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
{% set title = i18n.companyNumberTitle %}
{% block main_content %}
<form action="" method="POST">
{% include "partials/csrf_token.njk" %}
<div class="govuk-form-group">
{{ govukInput({
label: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
{% block main_content %}
<!-- The action will need to change depending on the location of the confirm-company page -->
<form action="" method="post">
{% include "partials/csrf_token.njk" %}
<h1 class="govuk-heading-l">{{i18n.isThisYourCompany}}</h1>
<dl class="govuk-summary-list">
<div class="govuk-summary-list__row">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
{% set title = i18n.nameRegisteredWithAmlTitle %}
{% block main_content %}
<form action="" method="POST">
{% include "partials/csrf_token.njk" %}
{{ govukRadios({
errorMessage: errors.nameRegisteredWithAml if errors,
classes: "govuk-radios",
Expand Down
1 change: 1 addition & 0 deletions src/views/features/sole-trader/nationality/nationality.njk
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
{% set dropdownThreeError = errors.nationality_input_2 %}
{% endif %}
<form action="" method="post">
{% include "partials/csrf_token.njk" %}
<fieldset class="govuk-fieldset">
<legend class="govuk-fieldset__legend govuk-fieldset__legend--l">
{% include "partials/user_name.njk" %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

{% set title = i18n.whatIsTheBusinessNameTitle %}
{% block main_content %}
<form action="" method="POST">
<form action="" method="POST">
{% include "partials/csrf_token.njk" %}
{% set textHtml %}
{{ govukInput({
label: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

<div>
<form action="" method="POST">
{% include "partials/csrf_token.njk" %}
{% include "partials/user_name.njk" %}

{{ govukDateInput({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
{% set title = i18n.whereDoYouLiveTitle %}
{% block main_content %}
<form action="" method="post">
{% include "partials/csrf_token.njk" %}
{% include "partials/user_name.njk" %}
{% set countryInput %}
<div id="typeahead-form-group" class="govuk-form-group">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
{% block main_content %}
<div class="govuk-width-container">
<form action="" method="POST">
{% include "partials/csrf_token.njk" %}
{% if businessName %}
{% include "partials/business_name.njk" %}
{% endif %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
{% endfor %}
{# Form section #}
<form action="" method="POST">
{% include "partials/csrf_token.njk" %}
{% if businessName %}
{% include "partials/business_name.njk" %}
{% endif %}
Expand Down
Loading

0 comments on commit c861a95

Please sign in to comment.