REST APIs, HTTP verbs and ACCESS LOGs - http

I've been trying to follow good RESTful APIs practices when designing them. One of them which happens to be very simple and common keeps getting hard to follow:
Use GET http verb to retrieve resources
Why? Consider you have a URI to get account information like this:
http://www.example.com/account/AXY_883772
Where AXY_883772 is an account id in a bank system. Security auditing will raise a warning stating that:
Account ID will appear on HTTP ACCESS LOGS
Account ID might get cached on browser's history (even though is unlikely to use a browser regularly to access a RESTful API)
And they end up by "recommending" that POST verb should be used instead.
So, my question is:
What can we do about it? Just follow security recommendations and avoid using GET most of the times? Use some kind of special APACHE/IIS/NGINX access log configuration to avoid logging access to certain URLs?

If you have sensitive information in your urls, and you are logging urls you are logging sensitive information.
So there's two obvious solutions:
Don't log the url
Use a different url that doesn't contain the sensitive information
The last one could be implemented by using some (different) id that your server maps back to the normal id.
If neither of those solutions are an option for you, then you cannot use GET and therefore it's not good RESTful design.
I realize all these things are probably already obvious to you; But it's the most accurate answer I could give.
It's worth nothing that this doesn't just apply to GET, it would actually also be the case for PUT, DELETE and often POST.

Related

Restrict access in firebase

I am making a web app using firebase. I was looking into restricting access to certain pages unless there's a subscription. When I looked through the docs all I found was that I could do transactions with stripe and it only applied on signing in and up not restricting pages.
After searching on the internet, I didn't find a viable solution, but three ideas came up to me I could use (which are either with low working possibility or very lackluster to say the least. (all include using stripe.))
One: I would use a middleware to verify the token I get from stripe and then redirect from there. (but all that comes to my mind how I would identify the redirected page in the middleware. And even if that was probable how much time would that take to make it work(if that even is possible), I have no idea.)
Two: in hosting configurations I could call a function when a rewrite is performed. I thought I could call a make a function that verifies the token from the strip when a restricted page is called. (But then again not only is the function accessible after hosting and can be viewed, I don't know if I can call firebase configurations and functions inside the firebase.json.)
third: this is the most viable but has very bad downsides, is authenticating the strip token from in a regular javascript, and if it fails it would restrict the access to the page. Do the same in the rules so that the database section related to that page. (the downside is that the HTML, CSS, and javascript would all be accessible. Only the database functions relating to them are restricted.
So with all that being said, I couldn't find any viable option I could use. So I was wondering if anyone in here have met the same problem and got a solution or do you have any advice I could use.
Note: I am using firebase's realtime database by the way.
If you are trying to restrict access to your webpages/app, you should come up with a logic in your backend or frontend (depending on your app structure) where you could store values needed in Firestore or another solution.
In case you would like to restrict access to Firestore, you can achieve that with Rules.

Authorising users in an ASP.NET (MVC5) web api project

Ok, so I'm struggling a little bit with trying to get a authentication process in my ASP.NET MVC5 (Web API 2) project. To start, here are some requirements:
I can't use Entity Framework (all access to the DB needs to be done through stored procedures)
Needs to target .NET Framework 4.5.2
I am not using ASP.NET Core
I would like to be able to use Bearer (or similar) tokens for authentication
I would like to invalidate tokens if a user logs out or automatically invalidate them after 24 hours
I would like to pass (and receive) XML when sending requests to the "login" (or "token") endpoint (note that ideally the solution should respect the "Content-Type" and "Accepts" headers, so if I send it JSON it should respond in JSON, and if I send it XML it should respond in XML)
I will not be using external providers (e.g. Google) anytime soon (maybe never)
I would like to use the <Authorize> attributes to help with protecting other endpoints
I am using VB.NET, although answers to this question can be in C# (I can convert them or rewrite them to suit)
I would like to store the tokens in the database so I can record which user is doing what within the API
(note that there are lots of reasons why I can't change the above)
I've tried to do this with Owin (OAuth) but I've found the following issues when comparing this to the requirements:
I can't seem to send the token endpoint any XML
Responses from the authentication endpoints (both successful and unsuccessful) are in JSON
I can't invalidate the tokens when logging out
I am happy to move away from OAuth if that is the best way to go for what I want. I would prefer to use Microsoft built nuget packages (ie no third party solutions) or I'm happy to partially roll my own solution (I would like to leverage as much of in-built or Microsoft built code, including Identity and Claims as possible so I can minimise testing efforts).
I have read numerous StackOverflow questions about this and search heaps on the internet, but most articles stick with OAuth despite the above issues or they rely on EntityFramework. My current solution uses the code from here (pretty much copy/pasted with some custom code in ApplicationOAuthProvider.GrantResourceOwnerCredentials()): https://www.codeproject.com/Articles/1187872/Token-Based-Authentication-for-Web-API-where-Legac
Thanks for the help!
I did some more extensive research and it looks like OAuth is not applicable for my specific situation. Although it seems like a nice authentication method, I really need to invalidate tokens via the DB, and I need the API to always send/receive XML (these are apparently not applicable when using OAuth).
To solve these problems, I have rolled my own token-based solution that creates a hashed token on the client side, so I never send passwords over the wire (which is a little bit nicer) because the token is generated on the client side (note that I am controlling what happens on the client side - these are all in house clients and I am writing the libraries these clients will use). This involved me creating my own filter which inherits System.Web.Http.AuthorizeAttribute.
If anyone stumbles across this question and provides a really good answer, I'm more than happy to mark theirs as accepted.

In my meteor app, how do I make authenticated google API calls on behalf of my user?

Background: This is my first standalone web development project, and my only experience in Meteor is building the Discover Meteor app over the last summer. I come from about a year of CS experience as a side interest in school, and I am most comfortable with C and C++. I have experience in python and java.
Project so far: I'm creating a calendar management system (for fun). Using accounts-google, I have created user accounts that are authenticated through google. I have requested the necessary permissions that I need for my app, including 'identity' and 'calendar read/write access'. I've spent the last week or so trying to get over this next hurdle, which is actually getting data from google.
Goal: I'd like to be able to make an API call to Calendar.list using a GET request. I've already called meteor add http to add the GET request functionality, my issue comes with the actual implementation.
Problem: I have registered my app on the developer console and set up Accounts using the client ID and secret, but I have not been able to find/generate my 'API key' for use in the request. Here is the google guide for creating the access token by using my (already) downloaded private key. I'm having a hard time wrapping my head around an implementation on the server side using JS because I don't have a lot of experience with what is mentioned in the HTTP/REST portion of the implementation examples. I would appreciate some help on how to implement a handshake and receive an access token for use in my app. If there is a call I can make or some package that will handle the token generation for me, that would be even better than implementation help. I believe an answer to this would also benefit this other question
The SO answer that I've been referring to so far: https://stackoverflow.com/a/14543159/4259653 Some of it is in spanish but it's pretty understandable code. He has an API key for his request, which I asked this question to help me with. The accounts-google documentation isn't really enough to explain this all to me.
Also an unrelated small question: What is the easiest way to deal with 'time' parameters in requests. I'm assuming JS has some sort of built-in functionality that I'm just not aware of yet.
Thanks for your research. I have also asked a very similar question, and right now I am looking into the package you recommend. I have considered this meteor-google-api package, but it looks abandoned.
Regarding your question about time manipulation, I recommend MomentJS. There are many packages out there; I am using meteor add mrt:moment
EDIT: MomentJS now has an official package for Meteor, so use meteor add momentjs:moment instead of the mrt command above
Below is a snippet of what moment can do. More documentation here.
var startTimeUTC = moment.utc(event.startTime, "YYYY-MM-DD HH:mm:ss").format();
//Changes above formatting to "2014-09-08T08:02:17-05:00" (ISO 8601)
//which is acceptable time format for Google API
So I started trying to implement all of this myself on the server side, but was wary of a lot of the hard-coding I was doing and assumptions I was making to fill gaps. My security prof. used to say "never implement encryption yourself", so I decided to take another gander for a helpful package. Revising search criteria to "JWT", I found jagi's meteor-google-oauth-jwt on Atmosphere. The readme is comprehensive and provides everything I need. Following the process used in The Google OAuth Guide, an authorization request can be made and a key generated for making an API call.
Link to Atmosphere: https://atmospherejs.com/jagi/google-oauth-jwt
Link to Repo: https://github.com/jagi/meteor-google-oauth-jwt/
I will update this answer with any additional roadblocks I hit in the Google API process and how I solved them:
Recently, I've been running into problems with the API request result. I get an empty calendarlist back from the API call. I suspect this is becuase I make an API call to my developer account rather than to the subject user. I will investigate the problem and either create a new question or update this solution with the fix I find.
Fix: Wasn't including the 'sub' qualifier to the JWT token. Fixed by modifying JWT package token generation code to include delegationEmail: user.services.google.email after scope. I don't know why he used such a long designation for the option instead of sub: as it is in the google API, but I appreciate his package nontheless.
I'm quickly becoming proficient in this, so if people have meteor-related google auth questions, let me know.
DO NOT USE SERVICE ACCOUNTS AS POSTED ABOVE!
The correct approach is to use standard web access + requesting offline access. The documentation on the api page specifically states this:
Typically, an application uses a service account when the application uses Google APIs to work with its own data rather than a user's data.
The only exception to this is when you are using google apps domain accounts and want to delegate access to your service account for the entire domain:
Authorizing a service account to access data on behalf of users in a domain is sometimes referred to as "delegating domain-wide authority"
This makes logical sense as a user must be allowed to "authorise" your application.
Back to the posters original question the flow is simple:
1) Meteor accounts google package already does most of the work for you to get tokens. You can include the scope for offline access required.
2) if you are building your own flow, you will go through the stock standard process and calls as explained on auth
This will require you to:
1) HTTP call to make the original request or you can piggyback off some of the internal meteor calls : Package.oauth.OAuth.showPopup() -- go look at the source there are more nifty functions around there.
2) Then you need to create an Iron router server side route to accept the oauth response which will contain a code parameter that you will use to exchange for tokens.
3) Next use this code to make a final call to exchange the "code" for the token + refresh_token
4) Store these where ever you want - my requirement was to store them not at the user level but multiple per user
5) Use a package like GoogleAPI this wraps up Google API calls and refreshes when required - it only works when tokens are stored in user accounts so you will need to rip it apart a bit if your tokens are stored somewhere else (like in my case)

Will Google block my access if I use their features without token?

I'm using this link https://www.google.com/reader/api/0/stream/contents/feed/FEEDHERE?output=json&n=20
to fetch feeds using Google's algorithm. As you can see I'm not adding any other parameters, just fetching the returned data in JSON format. My app will be heavily used hopefully and if I send a lot of requests to this link, will Google block my access or something?
Is there anything I can include, like userip, url for my app (so if they have problem to just contact me) or something else?
The most basic answer to your question is that Google will change its Terms of Service whenever it likes, and you've got no say in the matter. So if it's allowed today, it might not be allowed tomorrow, at Google's whim.
On this issue, though, you seem fairly safe. From the Terms of Service (these is the general document, since Reader doesn't seem to have a specific one):
Don’t misuse our Services. For example, don’t interfere with our Services or try to access them using a method other than the interface and the instructions that we provide.
Google provides RSS and Atom. They provide these feeds, so I assume they expect that they'll be used. They don't say that it's a misuse to point someone else at those feeds, so it looks OK for now, but they could add such a clause at any time.
All online services are subject to the terms and conditions of the providers of those services. So, as others have said, they may be ok with your use today, but they can change their mind any time down the line. I doubt including a URL or email or contact info will help anything, because when these services change, they don't notify every user of the service, they just announce the change publicly, and usually they give several month's notice in order to give users a chance to adapt their applications, but this is not standardized or enforced so there is no guarantee. One example would be the fairly recent discontinuance of the Google Finance API (for which no replacement has been announced).
The safest approach would be to design your app such that this feature that uses google's functionality is decoupled as much as possible from the rest of your app, so that, when or if the availability of the service changes (ie it's no longer available at all) you can adapt your app to use some other source for the feeds with minimal impact to the rest of the app. Design for change and plan for the worst.

How should I build a good (web) API

I'm going to build an API for a web app and I'm interested in what people can suggest as good practices.
I'm already planning to make it versioned (version 1 can only control certain aspects of the system, version 2 could control more, but this may need a change in the way authentication is performed that would be incompatible with version 1), and the authentication will be distinct from the standard username/password people use to log in (if someone does use a malicious tool it won't open them up to full impersonation, just whatever the api allows).
Does anyone have further ideas, or examples of sites with particularly good APIs you have used?
Read the RESTful Web Services book, which give you a good overview of how to use REST in practice, and get to up to speed quickly enough to get started now, with some confidence. This is more useful than just looking at an existing API, because it also discusses design choices and trade-offs.
1) Bake the version number directly into the URL rather than passing it as a parameter, since that gives you complete freedom to change the organization of your API namespace with each version bump.
2) Keep your URL rewriting rules (if any) as simple/lean as possible (but no simpler), while making your URLs as beautiful as possible (but no more).
3) Always look for the best HTTP status code you can find for each response (and don't forget about 202 and 207, for example).
4) Implement fascist parameter validation logic, and informative error messages.
5) Use HTTP request headers where appropriate instead of parameters (like Accept, for example, to allow clients to specify the desired data format of the response).
6) Organize your "nouns" in such a way that the URLs used by different client audiences are separated near the "root" of your URL tree (this makes it easier to enforce different authentication mechanisms for those different audiences if needed, or even map different portions of your URL tree to different servers).
7) If you're serving regular web pages off the same domain as your APIs and use the same authentication credentials, require an X-Requested-With header in your API requests so as to avoid XSRF vulnerabiities.
I would take a look at proven APIs:
YouTube API
Twitter API
There's a lot of argument about whether these APIs are "good" but I think their success is demonstrated, and they're all easy to use.
Use REST.
RESTful web services architecture is easy to implement and uses the strengths and semantics of HTTP for what they were intended. It's resource-oriented, just like the web itself.
Amazon Web Services, Google and many others offer REST APIs to interact with their products.
Use REST.
Read up on standards for APIs, or copy the ideas from one of the popular ones.
Be careful when authenticating users.
Start very very simple.
Build a site that uses your API (even if it's not useful) to check things work. Perhaps you could build a mobile version of the site or something that forces you to use the API in a lot of depth.

Resources