How to access Request Specific Data in Go? - go

I have an API written in go and I am using the gin-gonic framework to implement my endpoints. I am following clean architecture for my project which means that my entire application is divided into multiple layers namely - Controller, Service, Repository, And Session. The endpoints are secured by auth0 and the validation is carried out in a gin middleware. In the middleware I can extract the Subject from the JWT (Set in the header)
Now, here's my question. I want to use this subject value in my queries. I was wondering if I can store the Subject (sub) in the context and use it in other parts of my code WITHOUT PASSING CONTEXT AROUND. Is this possible? Or do I simply have to update all my functions and add a new parameter "Sub" to all downstream calls?
I am alluding to using a Global Variable of sorts to access Request Specific Data (SUB from the JWT token). I know it's a bad practice- I am just wondering if there is any other way to accomplish this other than passing around request specific data? Any help is appreciated.

It is really the whole point of the context - it exists to hold these kinds of things and to be passed around the chain. It's important because you want to keep it scoped to the request -- if you start using globals you could run into issues where you get contention because multiple requests are messing with the same data. Likewise if the token was invalidated between requests.
If your authentication middleware runs before your query (which it sounds like it does) then it should be simply a matter of having it put the subject in the context in a way you're happy with.

Related

Should I use a Web API 2.2 custom filter or message handler?

I am building a Web API service which will accept 2 of 4 possible tokens in the header. These tokens are used for different purposes but will all be able to be resolved (using lookup in a DB and other operations) to a couple of key pieces of user data.
Only a limited number of endpoints in my controllers will need to receive this information and so I need to know if I should be building a message handler (I believe this is executed for all requests) or a custom action filter (attached via attributes to the specific endpoints.)
Which method is most appropriate for retrieving data from the request header, using it to retrieve user information and populating the header/request with the retrieved data for the controller to use?
Token is an over-loaded term but if you are using "token" as in security token meant for authentication, you can create an authentication filter. If your tokens are just identifiers using which you pull more data from a data store, action filter is a good choice. As you said, message handlers run for all requests (per-route or global granularity) and may not be a good candidate. However, message handlers run earlier in the pipeline and action filters run just before the action method. So, in future, if any other component in your Web API pipeline needs this data, action filter could be too late. If you know for sure only controllers will ever need this data, action filter is probably the best place, given the granularity they provide.

Can requests via Ajax to make direct db queries ever be made secure?

Suppose you would format your urls so that you could make direct model queries with a request using Ajax.
Making a query in Django:
MyModel.objects.get(id=4)
Making a query via request to url using Ajax:
/ajax/my-model/get/id/4/
The problem is that this presents a huge security problem, any user that knows how to make requests via Ajax could query the database by recognising that the url corresponds to a query of a specific model. However, if these kind of queries could be made secure, it would allow for much more well structured/reuseable client side code imo.
But I simply don't see how this can be made secure. I just want to make sure if this suspicion is correct.
Never trust input from the client. I think this is a very general rule in web development and applies to any request the client does. I think you have a couple options here:
use Django's internal Authorization mechanism. This is not authentication! Like this you can limit resources to be accessed to specific users only. Also look into reusable django apps, which seem to take some complexity out of that topic.
validate every input from the client. This is mostly for requests which are supposed to change data).
use an API framework like django-tastypie or django-restframework, which are easily plugable with your models and offer authentication and authorization out of the box.
In Django, such views will be protected by its authentication mechanism. It is possible to design the view so it will only allow specific users to query specific queries.

Hot Towel/Durandal/Breeze.js: how to vertically secure data calls?

I'm new to the whole client-side SPA world. I'm using the above technologies, which seem quite promising. However, one huge snag that I can't get over easily is the lack of built-in security. I had to manually roll out the user authorization, which IMHO should be part of the framework.
Now that I have that sorted, I'm getting major headaches with vertical security: where one user is logged in but can easily access other users' info by changing a few parameters in the browser console. I could pass the userId with every call and then compare it with the one on the server, but I was hoping that there would be an overarching solution that doesn't pollute the breeze data calls with user ids.
For example, let's say there's a call from the data service like this:
function getItems(){
var query = breeze.EntityQuery.from('Items').expand("Person");
return manager.executeQuery(query);
}
this will get all the items, not good. So let's limit by userId:
function getItems(userId){
var query = breeze.EntityQuery.from('Items').where("userId", "==", authentication.userId).expand("Person");
return manager.executeQuery(query);
}
in the second example, we get the userId from the authentication service, which stored the userId when the user was logged in. However, a malicious user can easily go the browser console and change that value.
Of course, I could pass the userId using withParameters(...) and compare it with the current one on the server, but I'd have to do that for every call, which doesn't seem right. Is there a better way to secure calls with the trusted user id?
#Ali - I understand your pain and your concern. You are right to fear any form of so-called security that relies on information passed in the URL. Fortunately there are excellent answers to your concerns and Breeze apps work well with them.
For example, have you studied the ASP.NET Breeze/Knockout Template? It uses Forms Auth for authentication and guards the Web API controller with an [Authorize] attribute. Only logged-in users can access any of the controller methods.
That authentication also sets the IPrincipal which the Web API controller makes available through its User property. You'll see User passed to the constructor of the TodoRepository. In that repository you'll find guard logic to restrict query and saves to just the Todo information belonging to the requesting user.
Look at the network traffic. You won't find any user identifying information in the URL or the request/response bodies. You will see an encrypted authentication cookie in a header.
An obvious flaw in the example is that the client/server traffic takes place in the clear. You must add transport level security (HTTPS) before you go to production. But this is a demo after all.
Why not just do this in the controller?
If the Web Api is secured with [Authorize] then you can get the users ID in the controller and make sure that the data returned is for the currently logged in user.

Securing AJAX Requests via GUID

I'm writing a web app that will be making requests via AJAX and would like to lock down those calls. After a little research, I am considering using some form of random token (string) to be passed back along with the request (GUID?). Here's the important parts of my algorithm:
Assign a token to a JavaScript variable (generated server-side).
Also, store that token in a DB and give it a valid time period (i.e. 10 minutes).
If the token has still not been used and is within it's valid time window, allow the call.
Return requested information if valid, otherwise, log the request and ignore it.
With an eye toward security, does this make sense? For the token, would a GUID work - should it be something else? Is there a good way to encrypt variables in the request?
EDIT:
I understand that these AJAX requests wouldn't be truly "secure" but I would like to add basic security in the sense that I would like to prevent others from using the service I intend to write. This random token would be a basic, front-line defense against abusive calls. The data that would be requested (and even submitted to generate such data) would is HIGHLY unlikely to be repeated.
Maybe I'm wrong in using a GUID... how about a randomly generated string (token)?
If you are doing this to trust code that you sent to the client browser, then change direction. You really don't want to trust user input, which includes calls from js that you sent to the browser. The logic on the server should be made so that nothing wrong can be done through there. That said, asp.net uses a signed field, you might want to go that way if absolutely necessary.
Expanding a bit:
Asp.net tamper-proofs the viewstate, which is sent as a html hidden field (depending on the configuration). I am sure there are better links as reference, but at least it is mentioned on this one: http://msdn.microsoft.com/en-us/library/ms998288.aspx
validation. This specifies the hashing
algorithm used to generate HMACs to
make ViewState and forms
authentication tickets tamper proof.
This attribute is also used to specify
the encryption algorithm used for
ViewState encryption. This attribute
supports the following options:
SHA1–SHA1 is used to tamper proof
ViewState and, if configured, the
forms authentication ticket. When SHA1
is selected for the validation
attribute, the algorithm used is
HMACSHA1.
A link for the .net class for that algorithm http://msdn.microsoft.com/en-us/library/system.security.cryptography.hmacsha1.hmacsha1.aspx.
Update 2:
For tamper-proofing you want to sign the data (not encrypt it). Note that when using cryptography in general, you should really avoid using a custom implementation or algorithm. Regarding the steps, I would stick to:
Assign a token to a JavaScript variable (generated server-side). You include info to identify the request and the exact date&time where it was issued. The signature will validate the server side application issued the data.
Identify double submits if appropriate.
That said, the reason asp.net validates the viewstate by default, is because devs rely on info coming in there as being handled only by the application when they shouldn't. The same probably applies for your scenario, don't rely on this mechanism. If you want to evaluate whether someone can do something use authentication+authorization. If you want to know the ajax call is sending only valid options, validate them. Don't expose an API at granularity level than the one where you can appropriately authorize the actions. This mechanism is just an extra measure, in case something slipped, not a real protection.
Ps. with the HMACSHA1 above, you would instantiate it with a fixed key
It really depends on what you're trying to accomplish by security. If you mean prevent unauthorized use of the HTTP endpoints there is very little you can do about it since the user will have full access to the HTML and JavaScript used to make the calls.
If you mean preventing someone from sniffing the data in the AJAX requests then I would just use SSL.
A GUID used in the way that you're suggesting is really just reinventing a session id cookie.
"Securing" is kind of a vague term. What exactly are you trying to accomplish? Using a GUID is a perfectly fine way to prevent duplicate submissions of the same request, but that is all.
If the information being passed between the client and server is truly sensitive, you should do it over HTTPS. That's really the only answer as far as securing the actual communication is concerned.
Edit: To answer your question regarding whether a GUID is the "right" way - there is no right way to do what you're suggesting. Using any token, whether it's a GUID or something of your own creation, will not have any effect other than preventing duplicate submissions of the same request. That's it.

Can you help me understand this? "Common REST Mistakes: Sessions are irrelevant"

Disclaimer: I'm new to the REST school of thought, and I'm trying to wrap my mind around it.
So, I'm reading this page, Common REST Mistakes, and I've found I'm completely baffled by the section on sessions being irrelevant. This is what the page says:
There should be no need for a client
to "login" or "start a connection."
HTTP authentication is done
automatically on every message. Client
applications are consumers of
resources, not services. Therefore
there is nothing to log in to! Let's
say that you are booking a flight on a
REST web service. You don't create a
new "session" connection to the
service. Rather you ask the "itinerary
creator object" to create you a new
itinerary. You can start filling in
the blanks but then get some totally
different component elsewhere on the
web to fill in some other blanks.
There is no session so there is no
problem of migrating session state
between clients. There is also no
issue of "session affinity" in the
server (though there are still load
balancing issues to continue).
Okay, I get that HTTP authentication is done automatically on every message - but how? Is the username/password sent with every request? Doesn't that just increase attack surface area? I feel like I'm missing part of the puzzle.
Would it be bad to have a REST service, say, /session, that accepts a GET request, where you'd pass in a username/password as part of the request, and returns a session token if the authentication was successful, that could be then passed along with subsequent requests? Does that make sense from a REST point of view, or is that missing the point?
To be RESTful, each HTTP request should carry enough information by itself for its recipient to process it to be in complete harmony with the stateless nature of HTTP.
Okay, I get that HTTP authentication
is done automatically on every message
- but how?
Yes, the username and password is sent with every request. The common methods to do so are basic access authentication and digest access authentication. And yes, an eavesdropper can capture the user's credentials. One would thus encrypt all data sent and received using Transport Layer Security (TLS).
Would it be bad to have a REST
service, say, /session, that accepts a
GET request, where you'd pass in a
username/password as part of the
request, and returns a session token
if the authentication was successful,
that could be then passed along with
subsequent requests? Does that make
sense from a REST point of view, or is
that missing the point?
This would not be RESTful since it carries state but it is however quite common since it's a convenience for users; a user does not have to login each time.
What you describe in a "session token" is commonly referred to as a login cookie. For instance, if you try to login to your Yahoo! account there's a checkbox that says "keep me logged in for 2 weeks". This is essentially saying (in your words) "keep my session token alive for 2 weeks if I login successfully." Web browsers will send such login cookies (and possibly others) with each HTTP request you ask it to make for you.
It is not uncommon for a REST service to require authentication for every HTTP request. For example, Amazon S3 requires that every request have a signature that is derived from the user credentials, the exact request to perform, and the current time. This signature is easy to calculate on the client side, can be quickly verified by the server, and is of limited use to an attacker who intercepts it (since it is based on the current time).
Many people don't understand REST principales very clearly, using a session token doesn't mean always you're stateful, the reason to send username/password with each request is only for authentication and the same for sending a token (generated by login process) just to decide if the client has permission to request data or not, you only violate REST convetions when you use weither username/password or session tokens to decide what data to show !
instead you have to use them only for athentication (to show data or not to show data)
in your case i say YES this is RESTy, but try avoiding using native php sessions in your REST API and start generating your own hashed tokens that expire in determined periode of time!
No, it doesn't miss the point. Google's ClientLogin works in exactly this way with the notable exception that the client is instructed to go to the "/session" using a HTTP 401 response. But this doesn't create a session, it only creates a way for clients to (temporarily) authenticate themselves without passing the credentials in the clear, and for the server to control the validity of these temporary credentials as it sees fit.
Okay, I get that HTTP authentication
is done automatically on every message
- but how?
"Authorization:" HTTP header send by client. Either basic (plain text) or digest.
Would it be bad to have a REST
service, say, /session, that accepts a
GET request, where you'd pass in a
username/password as part of the
request, and returns a session token
if the authentication was successful,
that could be then passed along with
subsequent requests? Does that make
sense from a REST point of view, or is
that missing the point?
The whole idea of session is to make stateful applications using stateless protocol (HTTP) and dumb client (web browser), by maintaining the state on server's side. One of the REST principles is "Every resource is uniquely addressable using a universal syntax for use in hypermedia links". Session variables are something that cannot be accessed via URI. Truly RESTful application would maintain state on client's side, sending all the necessary variables over by HTTP, preferably in the URI.
Example: search with pagination. You'd have URL in form
http://server/search/urlencoded-search-terms/page_num
It's has a lot in common with bookmarkable URLs
I think your suggestion is OK, if you want to control the client session life time. I think that RESTful architecture encourages you to develop stateless applications. As #2pence wrote "each HTTP request should carry enough information by itself for its recipient to process it to be in complete harmony with the stateless nature of HTTP" .
However, not always that is the case, sometimes the application needs to tell when client logs-in or logs-out and to maintain resources such as locks or licenses based on this information. See my follow up question for an example of such case.

Resources