Adding a XSRF-TOKEN via a HTTP Interceptor causes a 400 Bad Request

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP

Adding a XSRF-TOKEN via a HTTP Interceptor causes a 400 Bad Request



Using a XSRF-TOKEN to prevent against XSRF attacks as I'm passing a JWT threw a cookie for my Angular app. Here is what my HttpInterceptor is looking like.


HttpInterceptor


intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>
const headerName = "XSRF-TOKEN";
const respHeaderName = "X-XSRF-TOKEN";
let token = this.tokenExtractor.getToken() as string;
if (token !== null && !req.headers.has(headerName))
req = req.clone( headers: req.headers.set(respHeaderName, token) );

return next.handle(req);



This causes a 400 Bad Request error to pop up in my console with a message reading: Response for preflight does not have HTTP ok status. If I comment out the line of code where the request is cloned, the error goes away, and my HTTP request goes through perfectly.



My headers in my .htaccess look like this.


.htaccess


Header set Access-Control-Allow-Origin "http://localhost:4200"
Header set Access-Control-Allow-Credentials "true"
Header set Access-Control-Allow-Headers "Content-Type"
Header set Access-Control-Allow-Headers "Authorization"
Header set Access-Control-Allow-Headers "X-XSRF-TOKEN"
Header set Access-Control-Expose-Headers: "Authorization"



Any help would be greatly appreciated, thanks.



EDIT 1: A MCVE of my PHP code


$return = array();

if (isset($_POST["email"]) && isset($_POST["password"]))

header("HTTP/1.0 200");
$return["msg"] = "random";
echo json_encode($return);

else

header("HTTP/1.0 400");
$return["error_message"] = "HTTP Post variables are not set!";
$return["friendly_error_message"] = "Client error!";
echo json_encode($return);



exit();



And my verify() function in my Angular service.


verify()


verify(email: string, password: string): Observable<JSON>
let headers = new HttpHeaders()
headers = headers.set("Content-Type", "application/x-www-form-urlencoded");
let body = new HttpParams();
body = body.set("email", email);
body = body.set("password", password);
return this.http.post<JSON>("http://localhost:80/verify", body, headers: headers, withCredentials: true, observe: "response" ).pipe(
map(res =>
return res.body;
),
catchError(this.handleError)
);



I've been testing with a "XSRF-TOKEN" session cookie by commenting/un-commenting a line of PHP code. When the session cookie is active, this error happens.



console



When I delete the cookie, I obviously don't have this problem because the req.clone() function never goes through as the conditional isn't met.


req.clone()





You have not shown your PHP code. Browsers will use OPTION request to your endpoint for "preflight". And it should return an "200 OK" response with proper headers.
– Koala Yeung
yesterday





I'll edit my post and throw in my PHP code later today. Thanks for the help!
– Jacob
21 hours ago





@KoalaYeung check out my edit :)
– Jacob
13 hours ago





Your PHP conditional would only return a "200 OK" when (a) it is a POST request; and (b) the POST body has the correct email and password. As I said earlier, a preflight request is always an OPTION request. Therefore your logic here would always return "400 Bad Request".
– Koala Yeung
11 hours ago





That makes sense but I guess I just don't understand why this whole "XSRF-TOKEN" thing I'm doing is messing everything up.
– Jacob
11 hours ago




1 Answer
1



Your server side code is not correctly responding to the preflight request for XSRF / CSRF workflow. You have to return a "200 OK" response to an OPTIONS request so your Angular plugin works:


<?php

$return = array();

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS')

// instead of doing that in .htaccess
header("Access-Control-Allow-Origin: http://localhost:4200");
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Allow-Headers: Content-Type");
header("Access-Control-Allow-Headers: Authorization");
header("Access-Control-Allow-Headers: X-XSRF-TOKEN");
header("Access-Control-Expose-Headers: Authorization");

// a 200 OK response to preflight with empty body
header("HTTP/1.0 200");

elseif (isset($_POST["email"]) && isset($_POST["password"]))

// presuming all request that are not a preflight
// must be a POST request.
header("HTTP/1.0 200");
$return["msg"] = "random";
echo json_encode($return);

else

header("HTTP/1.0 400");
$return["error_message"] = "HTTP Post variables are not set!";
$return["friendly_error_message"] = "Client error!";
echo json_encode($return);



exit();






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Comments

Popular posts from this blog

Executable numpy error

PySpark count values by condition

Mass disable jenkins jobs