Coder Social home page Coder Social logo

Comments (13)

raphaelbauer avatar raphaelbauer commented on July 19, 2024

Some more information copied from google groups:
https://groups.google.com/forum/#!topic/ninja-framework/KU4Hr6_3nZ8

The basics are already implemented:

  • Ninja session cookie can generate a unique id.
  • Don't allow javascript to read the session
    => That's the basic line of defense...

What is missing is:

  • A simple method to include the unique id into a form (if it's a form request for instance) => A tag or something to include into Freemarker rendering.
  • A filter to check whether the post request is valid. If the request parameter of the form is identical to the id in the cookie the request is not forged.

In one of our projects I wrote some custom code to do that, but we should include that into the framework. As I said above I'll attach some code to the issue.

from ninja.

raphaelbauer avatar raphaelbauer commented on July 19, 2024

Some code:

AuthenticityFilter:
public class AuthenticityFilter implements Filter {

public static final String AUTHENTICITY_TOKEN = "authenticityToken";

@Override
public Result filter(FilterChain filterChain, Context context) {

    Session session = context.getSession();
    String authenticityToken = context.getParameter(AUTHENTICITY_TOKEN);

    if (session.getAuthenticityToken().equals(authenticityToken)) {

        return filterChain.next(context);

    } else {

        return Results
                .forbidden()
                .template(NinjaConstant.LOCATION_VIEW_FTL_HTML_FORBIDDEN);

    }


}

}

from ninja.

raphaelbauer avatar raphaelbauer commented on July 19, 2024

The filter assumes your request contains a parameter called "authenticityToken". Authenticity token is generated and stored in the session via session.getAuthenticityToken() (already implemented).

But you have to include the parameter either via a query or post parameter right now..

from ninja.

noguespi avatar noguespi commented on July 19, 2024

How to display the token in the view ? now I'm using ${session.___AT} it it the right way ?

example :

<a href="${reverseRoute("controllers.DashboardController","logout","xsrf",session.___AT)}">logout</a>

from ninja.

raphaelbauer avatar raphaelbauer commented on July 19, 2024

hmm... in theory yes. But I think that's imperfect. getAuthenticityToken creates a new token when it's absent. session.___AT (in your view) does not do that.

So if you just include ${session.___AT} in your views you have to make sure that somewhere before in your controller session.getAuthenticityToken() has been called. Otherwise your view.ft.html will complain :)

As I write above:
"Missing: A simple method to include the unique id into a form (if it's a form request for instance) => A tag or something to include into Freemarker rendering."

If you want to contribute let us know!

from ninja.

noguespi avatar noguespi commented on July 19, 2024

Yes I noticed this issue, so what I'm doing is calling session.getAuthenticityToken upon user login or session generation.

I'm newbi with freemarker, why can't I call session.getAuthenticityToken from the template ?

from ninja.

raphaelbauer avatar raphaelbauer commented on July 19, 2024

That's because it's implemented as map and not as object.

Have a look at:
https://github.com/ninjaframework/ninja/blob/develop/ninja-core/src/main/java/ninja/template/TemplateEngineFreemarker.java

lin 239:
if (!context.getSession().isEmpty()) {
map.put("session", context.getSession().getData());
}

That puts the map of session into your Freemarker template. Therefore you cannot access getAuthenticity token.

There may be better ways to do this - contributions are welcome :)

from ninja.

mikehearn avatar mikehearn commented on July 19, 2024

I added this to my project, looks good!

@raphaelbauer Could a freemarker variable be set up to contain the token automatically? Then you just need something like

in your form, mark the controller method as FilterWith and you are done.

I wonder if POST methods should be filtered this way automatically though. That way, you are secure by default. I suppose, a controller can always be annotated with @NoXSRFProtect or equivalent if need be.

from ninja.

mikehearn avatar mikehearn commented on July 19, 2024

Of course github ate my markup instead of escaping it .... sigh.

The missing bit was a hidden HTML input field like [ input type="hidden" name="atoken" value="${atoken}" ]

from ninja.

raphaelbauer avatar raphaelbauer commented on July 19, 2024

Yes... totally agree - and that's really missing.

I guess there should be

  1. a helper that generates
    input type="hidden" name="atoken" value="${atoken}" ]
  2. A simple way to get hold of the session authenticity token. Best would be to inject the current session into the freemarker template. Then you can call session.getAuthenticityToken.

Are you interested in implementing something? We can certainly help :)

from ninja.

mikehearn avatar mikehearn commented on July 19, 2024

Maybe! My project is (a) really small and (b) behind where I should be :) so, not sure if I'll have time given that I probably only have two or three forms to XSRF protect. But I like Ninja so will dig in and see if I can make a patch in the coming weeks.

from ninja.

raphaelbauer avatar raphaelbauer commented on July 19, 2024

Cool... Let us know if we can help :)

from ninja.

svenkubiak avatar svenkubiak commented on July 19, 2024

Any update on this issue?

What about just passing the authenticity token to the template like e.g. prettime.

In TemplateFreemarkerEngine one could just add

   map.put("token", context.getSession().getAuthenticityToken());

and in the template just call

${token}

Thats what I just tested and it worked. Of course, this has to be done in a cleaner with, returning the complete form.

from ninja.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.