Hapijs validate params before authentication - javascript

I'm getting a bit confused about how Hapi handles validation, according to the request lifecycle (http://hapijs.com/api#request-lifecycle) validation of params / queries only happens after authentication has been done.
Does it make sense to do so? For example, I'm working on a public API, but I do not want to go through all the authentication logic if the request params are invalid.
Say a request with the following validation:
validate: {
name: Joi.string().required()
}
Why would the API go through the trouble of authenticating the user when the request will be invalid due to name not being send?
Or is this me just misunderstanding the request lifecycle?

When validation fails, hapi returns information about why the validation failed. In your example, the route requires a parameter called name. For security reasons you might not want to tell an unauthenticated user that this route requires this parameter. That gives away a lot of information right?
For me personally I think there are a few reasons why authentication is done first:
What's more important, telling the user they are not authorized to access an endpoint, or that their request was invalid? I think authorization is more important.
For security reasons, don't reveal any more information than is absolutely necessary.
Once you establish your authentication method, the amount of "work" to authenticate a request is the same, but validation can vary a lot between requests. One route might have many parameters that need to be validated. So if you had to average out the cost of a failed request, authentication might be cheaper over many, many requests. (see JWT authentication)

Related

Is using a query string in POST request a bad practice?

There is a system that sends POST requests from frontend to backend. These POST requests do not use the body to pass the data to the server; instead, it uses query strings in the URL params.
These requests do not send files or JSON, only several string params.
W3C does not describe that situation https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
Is it a bad practice to use query strings for POST requests, and if there any negative consequences of using that from security or performance or architecture reasons?
Are there any conventions that define the usage of body or query strings for different types of requests?
Reminder: In 2014, RFC2616 was replaced by multiple RFCs (7230-7237).
Is using a query string in POST request a bad practice?
Not if you know what you are doing.
Mechanically, it is all fine: are we allowed to use POST with a target-uri that includes a query-part? Yes. Are we allowed to use POST with an empty request body? Yes. Are we allowed to do both of those things at the same time? Yes.
The hard part: will this POST request invalidate the correct representations from the cache?
Cache-invalidation happens when the server returns a non-error response to an unsafe request (POST is an unsafe request method). The representations that are invalidated are those that match the target-uri of the unsafe request.
GET /foo?a=b HTTP/2.0
POST /foo?a=b HTTP/2.0
Here, if the POST is successful, the representations cached after the successful GET request will be invalidated in the cache.
GET /foo HTTP/2.0
POST /foo?a=b HTTP/2.0
Here, the effective request-uri is not the same, which means that general purpose components won't invalidate the cached representations of /foo.
There's nothing wrong with using query parameters in a URL in a POST request, with or without a request body. If it makes semantic sense for your request, it's fine. The POST method in itself has a semantic meaning distinct from GET, it doesn't require a request body to be useful, and the URL is yet distinct from that again. A classic example might be:
POST /foo/bar?token=83q2fn2093c8jm203
I.e., passing some sort of token through the URL.
There's no general security problem here, since anyone who could intercept this POST request to read the URL could also read its body data; you'll hardly find an attacker in a position that allows them to read the URL but not the body. However, URLs are typically logged in server access logs and browser histories, while request bodies aren't; that may or may not be worth considering, depending on what information you're transporting in those parameters and who has access to those logs.

CSRF-defense using Tokens

I'm designing a CSRF defense in a Grails 2.4.5 application.
I would like to use the Synchronizer Tokens pattern, and here is the design I intend, simplified:
With a new session, on the server, generate a long unique csrf token.
Store the csrf token in the session.
Add the csrf token to the response header
On the server, for every incoming request that will potentially change application state (post, update, delete...) validate that the referer/origin is the same as the target
On the server, for every incoming request that will potentially change application state (post, update, delete...) check the presence and validity of the csrf token in the header.
In a grails app, I imagine this taking place in the Spring Security filterchain.
If the token is not present or does not match, return an error and log a potential CSRF attack, otherwise allow the request to proceed.
Does this sound correct?
My concern is that it's not sufficient. Officially, the synchronizer token is added to every form and every post, put, or delete URL. Yet, the application doesn't use form tags, so it seems to be onerous to add it to every single JavaScript-generated form in the application, not to mention requiring extensive testing to make sure no existing functionality is broken.
Thanks!

JWT: handling token auth on a multi-domain-level

Currently I'm facing the following problem:
I'm building an application with a standalone login view.
Let's assume they both run on different domains. My login view communicates with a REST service on the server that issues a JWT token.
With this issued token the user should now be able to view (be forwarded to) the application. But this application - as mentioned - runs on another domain (or subdomain, maybe).
In my mind I tried the following:
Token is issued by the server. A hash is stored in a database and the hash is issued to the user. The hash is transferred to the application via URL and the applications checks the hash.
Token is issued by the server. The token is transferred to the user. When the user now opens the application (or is forwarded to...) the token should be transferred there, too. I have no clue how to do...
Both are not ideal ways, i know. But I really don't know how I can achieve that...
I hope anyone is able to help me with my thinkings?
If anything is unclear, just comment.
Thanks in advance!
Facebook, Twitter, Google, etc. offer OAuth by redirecting (302 Redirect Request). Basically your app starts if user has a valid token everything is fine, else it will open the Login-Page from the Identity Provider (e.g. Google) and return the token, if the login was successful.
This graphic shows the general steps:
https://www.soapui.org/soapui/media/images/stories/oauth2/oauth2flow.png
Hope this helps.
Lets assume you have two services in 2 different domains. One is your identity provider which generates tokens and holds the token <--> user assignment (we call it: idp.my.company). The other one is any application that does stuff but needs to login via idp.my.company (we call it app.my.company).
You have two scenarios:
1. Login without having a token aquired before.
2. Login with token.
Request GET: app.my.company
Response 302: Moved to: idp.my.company
Take a look which redirection type follows your needs (307 maybe)
https://en.wikipedia.org/wiki/URL_redirection
You need to add an information where to redirect back. In this case app.my.company.
[This happens automatically because of the Redirect] GET: idp.my.company/login.html.
Response 200 OK: idp.my.company/login.html
The User will now see the Login-Page of your IDP-Service and perform a Login.
Request POST: idp.my.company/login.html (or whatever)
The User posts his credentials to aquire a token
Response 302 Redirect: If login is successful, return token and now redirect to the origin site (app.my.company) which you provided earlier.
Request GET: app.my.company/afterlogin.html
The header contains a valid token
Response 200 Ok: Now the app.my.company service needs to check if the token is valid and if true return 200 Ok otherwise redirect again to IDP (start over at step 2).
This should be it. There could be errors but you should have a consistent picture of the process and get a grasp on how to implement it. Those steps cover scenario 1 and 2.

Create Groups in O365

Currently i am working on an App which will create groups in Office 365 programatically. I am wondering if this is possible using JavaScript. I also had another question regarding the Authentication and Authorization process. I am able to register the App and fetch the Authorization code. However when i try to fetch the Access token, it throws an error stating that it encountered a bad request. My Authorization URL is of the form:
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?
client_id=<some_client_id>
&scope=openid+profile
&response_type=id_token
&redirect_uri=<some_redirect_url>
&nonce=123456789
And my access token request url is:
https://login.microsoftonline.com/common/oauth2/v2.0/token?
grant_type=authorization_code
&code=<Code_generated_in_above_request>
&redirect_uri=<some_redirect_url>
&resource=https%3A%2F%2Fgraph.microsoft.com%2F
&scope=openid+profile
&client_id=<some_client_id>
&client_secret=<Some_client_secret>
If anyone could help me regarding my doubts, then it would be greatly appreciated. Thanks.
Microsoft Graph from JavaScript
Using Microsoft Graph from JavaScript works. HTTP requests to the REST endpoints with a valid access token will work great. You might also want to check out KurveJS (github:MicrosoftDX/kurvejs) for a simple library (handles authentication and some graph operations).
Authentication
If you are attempting client-side implicit flow, you can pass 'response_type=id_token+token' and avoid the second call. This will return you an access token in the resulting payload.
If you are attempting server-side authentication, you should pass 'response_type=code' and then make the second call for the access token with the resulting code.
References:
v2.0 Protocols - SPAs using the implicit flow
v2.0 Protocols - OAuth 2.0 Authorization Code Flow

Login through spring-security from javascript

We are working on application, where my friend is working on server side (spring) and he created REST api, and I'm creating client with angularJS. REST and client webpage are on different domains, so I had to faced Same-origin policy - I handled this with php proxy and everything works fine. Until yesterday - now we had authentication service (spring-security) and I have no idea how to login into REST. I can login when I simple write service adress into browser, but I cant get response I need when calling from JS.
When I'm sending simple get request, in response I'm getting HTML code with login page. I putted <form> to login on my page (taken from response, so it's exacly the same as on '/login' page, I just added full action adress), but after send data I'm getting error page with this message:
HTTP Status 403 - Invalid CSRF Token 'blah-blah-many-numbers-and-letters' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.
I'm not changing this CSRF token, so perhaps I don't know the proper way to handle this (now it's sending as paramaeter in POST from form - _csrf is hidden input with value attribute given by server).
So after this too long introduction, my question is: how to login into REST service (through spring-security) from angularJS controller? What is wrong in my way of doing this? (something has to be wrong, because it's not working ;)).
(Sorry for my english mistakes, I'm affraid there are many of them)
Angular have built-in support for CSRF but it use another name for CSRF Token.
If you already have CSRF Token repository in spring webservice, what have you to do is to change CSRF Token header name to XSRF-TOKEN.
You will find whole instruction how to solve your problem on https://spring.io/blog/2015/01/12/the-login-page-angular-js-and-spring-security-part-ii.
You can use Stateless authentication using server signed token i.e.JSON web token(JWT) for securing REST API's and using angularjs for client side implementation.
Please find the below link as reference for implementing the same:
http://blog.jdriven.com/2014/10/stateless-spring-security-part-1-stateless-csrf-protection/
Github:https://github.com/Robbert1/boot-stateless-auth
You need to have custom implementation of class AbstractAuthenticationProcessingFilter to avoid html response when you login into the Rest API.The blog and github reference will guide you in implementating the same.

Categories

Resources