Reputation: 1716
I am working on Ionic + Angular + NodeJs app to enable CSRF protection. It was working fine for sometime, but suddenly it stopped working with throwing me a message
ForbiddenError: invalid csrf token
My code is straightforward and I have banging my head since couple of days to find workaround for this, but it seems all tries failed.
Node JS server running on port 8089 (e.g) with CSRF protection
// [This is only for test purpose]
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "*");
res.header("Access-Control-Allow-Headers", "X-XSRF-TOKEN, Origin, X-Requested-With, Content-Type, Accept, Authorization");
next();
});
app.use(bodyParser.json({limit: '20mb'})); /* {limit: "20mb"} */
app.use(cookieParser());
const csrfProtection = csurf({
cookie: true,
ignoreMethods: ['GET', 'HEAD', 'OPTIONS'],
});
// base url is /api --> e.g (localhost:8089/api)
// it didn't worked with / only
app.use(config.base_url, csrfProtection, (req, res, next): void => {
res.cookie('XSRF_TOKEN', req.csrfToken(), { httpOnly: false });
next();
});
// csrfProtection is not yet applied
app.use(config.base_url, csrfProtection, HelperRouter); //post route
App Module in Ionic + Angular
@NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [BrowserModule,
IonicModule.forRoot(),
AppRoutingModule,
MenuComponentModule,
FontAwesomeIconsModule,
HttpClientModule,
HttpClientXsrfModule.withOptions({
cookieName: 'XSRF-TOKEN',
headerName: 'X-XSRF-TOKEN',
}),
],
providers: [
StatusBar,
SplashScreen,
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
{ provide: HTTP_INTERCEPTORS, useClass: CSRFTokenInterceptor, multi: true }
],
bootstrap: [AppComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
I also tried adding HttpInterceptor // this also didn't work
@Injectable({
providedIn: 'root'
})
export class CSRFTokenInterceptor implements HttpInterceptor {
constructor(private tokenExtractor: HttpXsrfTokenExtractor) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const headerName = 'X-XSRF-TOKEN';
const token = this.tokenExtractor.getToken() as string;
console.log(token);
if (token !== null && !req.headers.has(headerName)) {
req = req.clone({ headers: req.headers.set(headerName, token) });
}
return next.handle(req);
}
}
Also enabled proxy in Ionic + Angular app
{
"/v0": {
"target": "http://localhost:8089/api/",
"secure": false,
"logLevel" : "debug",
"changeOrigin": true
}
}
Response header
HTTP/1.1 403 Forbidden
x-powered-by: Express
access-control-allow-origin: *
server: nginx/1.19.0
date: Tue, 05 Jan 2021 11:38:10 GMT
content-type: text/html; charset=utf-8
content-length: 1018
connection: close
access-control-allow-methods: *
access-control-allow-headers: X-XSRF-TOKEN, Origin, X-Requested-With, Content-Type, Accept, Authorization
content-security-policy: default-src 'none'
x-content-type-options: nosniff
Request header
POST /v0/validateReferences HTTP/1.1
Host: localhost:4200
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0
Accept: application/json, text/plain, */*
Accept-Language: en-GB,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/json
Content-Length: 53
Origin: http://localhost:4200
Connection: keep-alive
Referer: http://localhost:4200/account/login
Cookie: _csrf=k5nvA7BbJQ9a2GvPdlpisfCQ
So what is going on
I have uploaded the project in GitHub in case someone would give it a try Project link
Upvotes: 0
Views: 994
Reputation: 1716
Finally, CSRF implementation is resolved. The completed implementation is in the GitHub project. GitHub
A few changes helped me to do the things first I changed the csrf get route root path
app.use('/', csrfProtection, (req, res, next): void => {
res.cookie('XSRF_TOKEN', req.csrfToken(), { httpOnly: false });
next();
});
Then I changed the proxy config file in ionic angular app
{
"/api/v0/*": {
"target": "http://localhost:8089/",
"secure": false,
"logLevel" : "debug",
"changeOrigin": true
} }
Then I changed my services to call the end points
/api/v0/validate // post route
I have added everything in the GitHub project, so if anyone faces CSRF issue, they can use the project.
Upvotes: 0