quarkiverse / quarkus-renarde

Server-side Web Framework with Qute templating, magic/easier controllers, auth, reverse-routing
Apache License 2.0
78 stars 19 forks source link

Quarkus fails to start when quarkus.csrf-reactive.enabled=false #156

Closed gbourant closed 11 months ago

gbourant commented 1 year ago

In the template tags/authenticityToken.html csrf is injected via {inject:csrf.token}. When the csrf is disabled the following exception is thrown io.quarkus.qute.TemplateException: tags/authenticityToken.html:1:64 - {inject:csrf.token}: @Named bean not found for [csrf]

FroMage commented 1 year ago

Why do you disable csrf?

gbourant commented 1 year ago

For the following two reasons

  1. When a user fills a form and it's not submitted for quarkus.csrf-reactive.cookie-max-age the request is not accepted.
  2. When you are building MVPs, you might not want to deal with csrf/security.
FroMage commented 1 year ago

When a user fills a form and it's not submitted for quarkus.csrf-reactive.cookie-max-age the request is not accepted.

Yeah, 10M is a bit low. Wouldn't raising it solve this?

When you are building MVPs, you might not want to deal with csrf/security.

Perhaps, but CSRF with Renarde should really be entirely transparent. Did you have experiences where it got in the way? I'd like to solve those :)

gbourant commented 1 year ago

Yeah, 10M is a bit low. Wouldn't raising it solve this?

I think that increasing the cookie age it will just postpone when it will fail, since Quarkus does not offer CSRF refresh mechanism.

Perhaps, but CSRF with Renarde should really be entirely transparent. Did you have experiences where it got in the way? I'd like to solve those :)

I'm currently developing a real estate application that features dynamic map-based area selection. If the user selects areas in the map for more than quarkus.csrf-reactive.cookie-max-age threshold, it will fail. (the page does not make full page reload upon map selection).

image

Also if i'm not mistaken, i had a quick look and quarkus.csrf-reactive.create-token-path is not respected by Renarde, instead it checks for CSRF cookie for all paths.

FroMage commented 11 months ago

Sorry about the delay. I have just fixed the reported issue, it should work now when you disabled csrf via config.

I think that increasing the cookie age it will just postpone when it will fail, since Quarkus does not offer CSRF refresh mechanism.

Actually, you can write an endpoint that will get you a CSRF token, fresh if expired:

public Application extends Controller {
 @Inject
 CsrfTokenParameterProvider csrf;

 public String csrf(){
  return csrf.getToken();
 }
}

Assuming you're using AJAX, you can precede your POST calls with a GET to refresh the token.

But you're right, 10 minutes is not long. Perhaps we should increase the default.

You can now use this in your AJAX call by adding it as a form parameter, or even a header: see https://quarkus.io/guides/security-csrf-prevention#csrf-request-header

Also if i'm not mistaken, i had a quick look and quarkus.csrf-reactive.create-token-path is not respected by Renarde, instead it checks for CSRF cookie for all paths.

Why do you think so? I'm entirely relying on the Quarkus CSRF extension now. Anything I missed?

gbourant commented 11 months ago

Since quarkus.csrf-reactive.enabled did not work at that time, i set up the quarkus.csrf-reactive.create-token-path=/randomUrl to avoid CSRF checking for all paths but instead it was still checking.

Shouldn't that have worked?

FroMage commented 11 months ago

The docs say:

Create CSRF token only if the HTTP GET relative request path matches one of the paths configured with this property. Use a comma to separate multiple path values.

So, that will mean you will never get a token, not that it would never be checked. Not sure how useful that is.

FroMage commented 11 months ago

I've fixed this now, so let's close this issue. We can work on other CSRF improvements in other issues.