I am following this tutorial for an application based in spring framework 3.2.4
http://springdiaries.blogspot.be/2012/12/web-security-preventing-csrf-attack.html#comment-form
The point is that I've checked all the objects in the session and I haven't found any object with the Key OWASP_CSRFTOKEN, and that is susposius that in not working well ?
This is not exactly an answer to your question, which is unfortunately too vague to answer without a magical crystal ball ^^, but here are some things you should try:
Check out your request is not coming from an URL matching one of the
the unprotected patterns defined in the
Owasp.CsrfGuard.properties configuration file (These values are
from the OWASP docs; you should have set up different ones):
.
org.owasp.csrfguard.unprotected.Tag=/Owasp.CsrfGuard.Test/tag.jsp
org.owasp.csrfguard.unprotected.JavaScriptServlet=/Owasp.CsrfGuard.Test/JavaScriptServlet
org.owasp.csrfguard.unprotected.Html=*.html
org.owasp.csrfguard.unprotected.Public=/MySite/Public/*
Check your web server / servlet container log for errors, both on startup / application load and upon receiving a client request.
Set breakpoints here and here and launch the application in
debug mode to make sure your class is being loaded and the token is
being requested.
Review one by one all the configuration parameters.
Read the project wiki and the docs carefully:
Configuration
Installation
User Manual
You won't have to modify your DB schema in anyway. That's not how OWASP CRSF guard works (the generated tokens are stored in-session, not persisted in the database).
It's also worth mention that you are following an outdated blog post: If you are using Spring you don't need to be using OWASP CSRF guard at all. You should be using spring-security authentication which has built in CSRF protection, which is much easier to set-up.
Check out the tutorial on this page on how to set up HTML form + SQL database based authentication with CSRF protection (Also, don't miss out the bcrypt password hashing one; It is very easy to set up and at some point you'll be glad you are storing safe hashes instead of clear text passwords).
You'll see you also won't have to modify the db at all to add CSRF protection using spring-security because the CSRF protection token is session-stored.
The set up takes 5-15 minutes; 30 minutes tops for a Spring neophite. In a nutshell, the framework takes care of generating and validating the token and returning an authentication error on invalid requests.
You just have to include the <csrf /> tag inside your spring-security.xml configuration file <http> tag.
If you are using html form based authentication, you'll also have to include the following hidden input inside the form:
<input type="hidden" name="${_csrf.parameterName}"
value="${_csrf.token}" />
Related
Hi I'm having issues security my application, enabling authenticated users access to specific endpoints, non-authenticated users access to others and most importantly, continuing to enable the application to communicate with itself, without storing passwords as a String in the case base.
The code base:
My code base consists of numerous packages that communicate via REST and GraphQL calls. With no authentication, this system works fine. Development is in Java 8 with Maven.
Aim:
I am currently in the process of adding authentication to the code base which should enable three things to occur.
The different projects in the application continue to communicate easily.
An "admin" user can log in and make calls either via Swagger or GraphiQL or any methods they require.
The average user will only be able to access specific endpoints such as UI elements (e.g. localhost:8082/user-ui [unique_key])
Current Development:
I've implemented Spring Security In-Memory Authentication (https://www.appsdeveloperblog.com/spring-security-in-memory-authentication/). Which successfully blocks URLs being called and prompts the user for credentials, except on certain predefined endpoints. This fulfilling criteria 3 and part of criteria 2 (as the Admin can access Swagger and GraphiQL).
My Problem:
Unfortunately setting up this system has broken the internal calls as the RestTemplate used to communicate between packages no longer has the correct authentication.
While I could use BasicAuthenticationInterceptor(https://www.baeldung.com/how-to-use-resttemplate-with-basic-authentication-in-spring) to provide the authorization, this would mean having to write the password in a String in the code base. As I understand it, this is bad form as the String is then stored in the String pool. Elsewhere I've managed to avoid this using the CharBuffer before encoding the password, however BasicAuthenticationInterceptorrequires a String.
Any advice on how to proceed would be greatly appreciated.
If you are using basic authentication, you will have to provide the password when you are making internal calls with resttemplate. That doesn't mean you need to store the sensitive data (in this case credentials for your basic authentication) in plain text in the code base. One of the most common practices is to use an external file to store the sensitive data and then get the application to use them at run time. You may also want to ignore that file from git repository to prevent that being part of the code base.
If you are using Spring boot have a look at the environment specific properties files, which could be an ideal way to store profile specific configuration and data like these.
https://docs.spring.io/spring-boot/docs/1.5.5.RELEASE/reference/html/boot-features-external-config.html
https://www.baeldung.com/properties-with-spring
If you are worried about storing the credentials in plain text in properties file, you can also encrypt sensitive data in your properties files.
Spring Boot how to hide passwords in properties file
No matter how I reason about it, it seems as if there is no secure way of implementing a client side rendered single-page-application that uses/accesses information on sessions for authentication, either via cookies, without severe compromise in security. I was mainly looking to building a React app, but it seems as if I will need to build it with SSR for a relatively secure version of authentication.
The use case that I'm especially thinking of is where the user logs in or registers and then gets a cookie with the session id. From there, in a server side implementation, I can simply set up conditional rendering depending on whether the server stored session has an associated user id or not and then pull the user information from there and display it.
However, I can't think of a client-side rendered solution where the user can use the session id alone on the cookie that isn't easily spoofable. Some of the insecure implementations would include using browser storage (local/session). Thanks.
I think the major issue here is that you are mixing the two parts of a web page (at least according to what HTML set out achieve) and treating them both as sensitive information.
You have two major parts in a web page - the first being the display format and the second being the data. The presumption in client side rendering / single page applications is that the format itself is not sensitive, and only the data needs to be protected.
If that's the case you should treat your client-side redirect to login behavior as a quality of life feature. The data endpoints on your server would still be protected - meaning that in theory an unauthenticated user could muck about the static HTML he is being served and extract page layouts and templates - but those would be meaningless without the data to fill them - which is the protected part.
In practice - your end product would be a single page application that makes requests to various API endpoints to fetch data and fill in the requested page templates. You wouldn't even need to go as far as storing complex session states - a simple flag notifying the client if it is authenticated or not would suffice (that is beyond what you would normally use for server-side authentication such as cookies or tokens)
Now let's say I'm a malicious user who is up to no good - I could "spoof" - or really just open the browser dev tools and set the isAuthenticated flag to true letting me skip past the login screen - now what would I do? I could theoretically navigate to my-service/super-secret without being redirected locally back to the login page on the client side - and then as soon as the relevant page tries to load the data from the server with the nonexistent credentials it would fail - best case displaying an error message, worst case with some internal exception and a view showing a broken template.
So just to emphasize in short:
A. If what you want to protect is your TEMPLATE then there is no way to achieve this clientside.
B. If what you want to protect is your DATA then you should treat gating/preventing users from navigating to protected pages as a quality of life feature and not a security feature, since that will be implemented on the server when serving the data for that specific page.
For a project I’m working on currently I am developing an API using Node/Express/Mongo and separately developing a website using the same tools. Ideally I want to host these on separate servers so they can be scaled as required.
For authentication I am using jsonwebtoken which I’ve set up and I’m generally pleased with how it’s working.
BUT…
On the website I want to be able to restrict (using Express) certain routes to authenticated users and I’m struggling a little with the best way to implement this. The token is currently being saved in LocalStorage.
I think I could pass the token through a get parameter to any routes I want to protect and then check this token on the website server (obviously this means including the jwt secret here too but I don’t see a huge problem with that).
So my questions are
Would this work?
Would it mean (no pun intended) I end up with ugly URLs
Would I just be better hosting both on the same server as I could then save the generated token on the server side?
Is there a better solution?
I should say I don’t want to use Angular - I’m aware this would solve some of my problems but it would create more for me!
First off, I'll answer your questions directly:
Will this work? Yes, it will work. But there are many downsides (see below for more discussion).
Not necessarily. I don't really consider ugly urls to include the querystring. But regardless, all authentication information (tokens, etc.) should be included in the HTTP Authorization HEADER itself -- and never in the URL (or querystring).
This doesn't matter so much in your case, because as long as your JWT-generating code has the same secret key that your web server does, you can verify the token's authenticity.
Yes! Read below.
So, now that we got those questions out of the way, let me explain why the approach you're taking isn't the best idea currently (you're not too far off from a good solution though!):
Firstly, storing any authentication tokens in Local Storage is a bad idea currently, because of XSS (Cross Site Scripting attacks). Local Storage doesn't offer any form of domain limitation, so your users can be tricked into giving their tokens up quite easily.
Here's a good article which explains more about why this is a bad idea in easy-to-understand form: http://michael-coates.blogspot.com/2010/07/html5-local-storage-and-xss.html
What you should be doing instead: storing your JWT in a client-side cookie that is signed and encrypted. In the Node world, there's an excellent mozilla session library which handles this for you automatically: https://github.com/mozilla/node-client-sessions
Next up, you never want to pass authentication tokens (JWTs) via querystrings. There are several reasons why:
Most web servers will log all URL requests (including querystrings), meaning that if anyone gets a hold of these logs they can authenticate as your users.
Users see this information in the querystring, and it looks ugly.
Instead, you should be using the HTTP Authorization header (it's a standard), to supply your credentials to the server. This has numerous benefits:
This information is not typically logged by web servers (no messy audit trail).
This information can be parsed by lots of standard libraries.
This information is not seen by end-users casually browsing a site, and doesn't affect your URL patterns.
Assuming you're using OAuth 2 bearer tokens, you might craft your HTTP Authorization header as follows (assuming you're representing it as a JSON blob):
{"Authorization": "Bearer myaccesstokenhere"}
Now, lastly, if you're looking for a good implementation of the above practices, I actually wrote and maintain one of the more popular auth libraries in Node: stormpath-express.
It handles all of the use cases above in a clean, well audited way, and also provides some convenient middlewares for handling authentication automatically.
Here's a link to the middleware implementations (you might find these concepts useful): https://github.com/stormpath/stormpath-express/blob/master/lib/authentication.js
The apiAuthenticationRequired middleware, itself, is pretty nice, as it will reject a user's request if they're not authenticating properly via API authentication (either HTTP Basic Auth or OAuth2 with Bearer tokens + JWTs).
Hopefully this helps!
Most frameworks I've looked at will insert into forms a hidden input element with the value being a CSRF token. This is designed to prevent user Bob from logging in on my site and then going to http://badsite.com which embeds img tags or JS that tell my site to execute requests using Bob's still logged in session.
What I'm not getting is what stops JS on badsite.com from AJAX requesting a URL with a form on my site, regex-ing the CSRF token from the hidden input element, and then AJAX posting to my site with that valid CSRF token?
It seems to me that you'd want to use JS to insert the CSRF token into the form at runtime, pulling the value from a cookie (which is inaccessible to badsite.com). However, I've not heard this approach mentioned and so many frameworks do the simple hidden input with the CSRF token, I'm wondering if my solution is over-engineered and I'm missing some part of what makes the hidden input method secure.
Can anyone provide some clarity? Thanks!
what stops JS on badsite.com from AJAX requesting a URL with a form on my site
The Same Origin Policy (unless you subvert it with overly liberal CORS headers). JavaScript running on a site can't read data from a site hosted on a different host without permission from that host.
There are workarounds to the SOP, but they all either require the co-operation of the host the data is being read from (JSON-P, CORS), or don't pass any data that identifies a specific user (so can't access anything that requires authorisation).
My company currently develops a Java web application. A couple of our clients have internal SAML servers (identity providers?) and have requested that we integrate with them. So recently I've been reading up on it and playing around with OpenAM. After about 3 days of this, I have a general understanding of it, but there are still some gaps in my knowledge. My hope is that someone can clear this up for me.
So here's how I imagine the workflow of a user logging in.
Let's define our customers SAML server as https://their.samlserver.com. So a user comes to our web application for a resource that's protected. Let's say that URL is http://my.app.com/something.
So if I'm correct, my.app.com is what SAML defines as a Service Provider. Our application realizes that this user needs to log in. We then present a page like this to the user...
<script>JQuery Script to auto submit this form on ready</script>
<form method="post" action="https://their.samlserver.com/Post/Servlet">
<input type="hidden" name="SAMLRequest" value="someBase64Data" />
<input type="submit" value="Submit" />
</form>
And that someBase64Data should be base64 encoded version of this...
<samlp:AuthnRequest
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
ID="identifier_1"
Version="2.0"
IssueInstant="2004-12-05T09:21:59Z"
AssertionConsumerServiceIndex="0">
<saml:Issuer>http://my.app.com</saml:Issuer>
<samlp:NameIDPolicy
AllowCreate="true"
Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"/>
</samlp:AuthnRequest>
So my first couple questions.
What is the ID value suppose to be?
And why can I declare myself as an Issuer?
Does the Identity Provider know about me? Maybe this is that Circle of trust I've been seeing on OpenAM. And if it does know about me, how does it know about me and what does it need to know?
So after the user is forwarded that page, they are taken to a page provided by the IDP https://their.samlserver.com. They authenticate on that page and the IDP does it's magic to validate the authentication and look up the user. After the authentication is successful, the IDP sends back a <samlp:Response> defined here.
A few more questions.
First, how does the <samlp:Response> get back to my web application so I can check it?
And what should I be looking for in that response to validate that it was successful? What does a failure look like?
We currently use the email address (LDAP) to identify users, so we'll probably grab that from the response and use that in the same way we do now. Anything else I should be mindful of in that response?
So now that we've checked that response for validity, we can grant the user a session like we do currently. But when they want to log out, is there a workflow for that? Do I have to notify the IDP that the user has left?
And finally, there are a couple of topics that have been thrown around in my reading and I'm not sure how they fit into this workflow. They are Circle of trust, Tokens, and Artifacts.
Thanks for any help everyone. I've found a lot of information in the last couple days, and it's possible that I could piece them together after a bit more playing. But I have yet to find a straightforward "Here's the Post" workflow article yet. Maybe that's because I'm wrong on how this works. Maybe it's because this isn't that popular. But I really wanted to make sure that I got the workflow so I didn't miss a crucial step in something as important as user authentication.
In response to your specific questions:
1.) What is the "ID" value supposed to be?
This should be a unique identifier for the SAML request. The SAML 2.0 specification states that it's really implementation specific how this is done, but makes the following recommendations:
The mechanism by which a SAML system entity ensures that the
identifier is unique is left to the implementation. In the case that a
random or pseudorandom technique is employed, the probability of two
randomly chosen identifiers being identical MUST be less than or equal
to 2 ^ -128 and SHOULD be less than or equal to 2 ^-160 in length.
This requirement MAY be met by encoding a randomly chosen value
between 128 and 160 bits in length.
2.) How does the IdP know about you?
Your SP needs to be registered with the IdP. To accomplish this, the SAML specification defines a format for "SAML Metadata" which tells the IdP where your SAML receivers are, what your certificates are, attributes you exchange, etc. OpenAM likely dictates some minimum requirements for configuring a trusted SP. This varies in each product.
3.) Where's the Response go, and what to check?
The Response will go to your Assertion Consumer Service (ACS) URL usually defined in the SAML Metadata you exchange from your SP with the IdP for initial setup. When you receive a SAML Response, you need to check many things - but most importantly, the SAML Status code should be "success", the inResponseTo ID's should match the request's sent ones and you must validate the digital signature on the Assertion. For that, you'll need to trust the IdP's public verification certificate, and you'll probably also want to do revocation checking.
4.) What about Logout?
SAML 2.0 also defines a profile for Single LogOut (SLO). This will not only log you out of the SP, but also the IdP and potentially any other SP's you've established a session with. It has a similar request/response flow as Single Sign-On (SSO), and thus similar things to set up and check (status codes, signatures, etc.).
So in short - this can be quite complex to implement from scratch. It's best to use tried & true libraries and/or products like Ian suggests. Companies like his have invested hundreds of hours of developer time to implement according to the spec and test interoperability with other vendors.
If you're just trying to set a single Java application up as a Service Provider, you should consider using a Fedlet from either Oracle (as a standalone ) or ForgeRock ( bundled with OpenAM ). The ForgeRock Fedlet has some issues interacting with Shibboleth 2.2.1 as an Identity Provider, but I find it to be somewhat simpler to configure and more informative.
Each has explicit instructions contained in the README to help you deploy. Once the Fedlet is configured and communicating with the IDP, the success page shows you all the code you need to integrate federated SSO into your application. It does the background work of sending and receiving AuthnRequests and Responses.
Scott's answer responds quite well to the questions you had, but I think that trying to write code on your own that generates the SAML is reinventing the wheel. The Fedlet was designed with precisely this use case in mind.