Disable caching of Web API responses - caching

I want to disable browser caching of all the Web API responses across all the clients. Even though I can use libraries like CacheOutput or CacheCow as suggested in Scott Hanselman's blog but my requirement is not that complex. I just want to disable caching of all the Web API responses and do not need any custom control over it.
How do I do that in ASP.NET Web API 2?
Which headers do I need to set? 'Cache-Control' : 'no-cache'?
Is ETag, Last-Modified, etc needed? Or maybe any other response headers??
It need to be implemented in a DelegatingHandler, right?

Just use the Cache-Control: no-cache header.
Implement it as delegating-Handler and make sure your header is applied (with MS Owin Implementation hook up on OnSendingHeaders(). I'm using it here OnSendingHeaders() Example).

Related

How do API work with CORS policies to serve multiple apps

I am creating an API that would serve data to my frontend app. The API is on api.myapp.com and the app on www.myapp.com (same domain, just another subdomain). They communicate with AJAX requests and CORS is all set up, working fine.
But I have another app on another domain (www.myotherapp.com) which partialy uses the same data as myapp, so I was thinking of reusing the API so myotherapp could requests data from it too.
I think it is one use case of API, to be reusable, right?
But then, there is something that I may have missed, because as my API has CORS enabled with "Access-Control-Allow-Origin: www.myapp.com", it won't allow other apps to use its endpoints, right? Their AJAX requests would fail with CORS policies.
So how are public API built and configured? How should I set my API so it can serve several apps (ideally, only the ones I allow)?
Thanks for the explanations :)
There is an Origin header in the request and your API should check if this header is one of the allowed. If it is, then return it as an Access-Control-Allow-Origin header.
If the API is public, it can returns * as Access-Control-Allow-Origin header.

Detect Request sent from Postman

I want to make a request to verify people's ID using laravel. Since it's very credential, I want to make it available only if they verify it from their mobiles.
So it must be prevented that the IDs are verified from postman request.
Is there a way to detect that a request is sent from postman or not?
Any idea would be very appreaciated :).
Thank you before
Postman has a tendency to send a header called something like postman-token so you could block the request if such a header exists.
Edit Note that this header can be turned off in postman settingss
As #EdwardChew wrote, this does NOT prevent people from using postman/curl/python/anything else. adding authentication to the endpoint is the best approach.
Sample postman request:
GET /api/car HTTP/1.1
Host: localhost:8080
Content-Type: application/json
cache-control: no-cache
Postman-Token: 05f5c492-3697-41b1-be0f-fb9bc4499b96
Since postman has the "code" feature, if the request is blocked it is simple to copy it as a curl command:
curl -X GET \
http://localhost:8080/api/car \
-H 'Content-Type: application/json' \
-H 'Postman-Token: e37790ea-a3a5-40cf-ac4c-b80184801f94' \
-H 'cache-control: no-cache'
and just deleting the line with the Postman-Token header. I normally do so when experimenting with APIs.
If you look at the Laravel doucmentation, there is a section on authorization: https://laravel.com/docs/5.8/api-authentication
which would force users to add a header token something like this: Authorization: Bearer 8fyew8f9yefo7o9yg98gyr and you would then be able to verify the caller
So it must be prevented that the IDs are verified from postman request.
Is there a way to detect that a request is sent from postman or not?
Checking that it comes from Postman is easy for requests sent from Postman where the boxes are checked for Postman-Token and/or User-Agent:
So you would add a check for them in your backend, but then the attacker would not send the Postman-Token header and for the User-Agent we will just send exactly the same one your mobile app/browser sends, thus easily bypassing your checks. By the way Postman is not the only tool, others exist like Insomnia, and then you also need to remember that requests may also come from a Proxy like mitmproxy, burp, zap, charlie, and many others. Do you get the point... it's not feasible to rely on headers to identify what is doing the request.
I highlighted the word what because who is in the request for your API backend is not the same as what is doing it.
The Difference Between WHO and WHAT is Accessing the API Server
In an article I wrote, entitled Why Does Your Mobile App Need An Api Key? you can read more about the difference between who and what is accessing your API server, but i will I quote the following from it:
The what is the thing making the request to the API server. Is it really a genuine instance of your mobile app, or is it a bot, an automated script or an attacker manually poking around your API server with a tool like Postman?
The who is the user of the mobile app that we can authenticate, authorize and identify in several ways, like using OpenID Connect or OAUTH2 flows.
So the who is the user of your API server that you will be able to Authenticate and Authorize access to the data, and the what is the software making that request in behalf of the user, your genuine web/mobile app, a tampered one, an automated script or someone manually poking around with your API via cURL, Postman or other similar tools.
By now I hope that you have enough knowledge to understand why the user(who) authentication is not the same as app(what) authentication/attestation.
POSSIBLE SOLUTIONS
I want to make a request to verify people's ID using laravel. Since it's very credential, I want to make it available only if they verify it from their mobiles.
It's not clear if you mean from a mobile browser or mobile app, but I will provide possible solutions for both.
For Mobile Apps
To learn how you can lock your API server to your mobile app I recommend you to read my answer to the question How to secure an API REST for mobile app? for the sections on Securing the API Server and A Possible Better Solution.
For web apps
Due to the nature of how the web was built, all you need is to hit F12 or inspect the page source, and then search for whatever you need to access the API server from another tool.
To learn some useful techniques to try that your API server only responds to requests coming from What you expect, your genuine web app, I invite you to read my answer to the question Secure api data from calls out of the app, specially the section dedicated to Defending the API Server.
DO YOU WANT TO GO THE EXTRA MILE?
I don't know if you already read some of the OWASP resources I am about to link, but in any response for a security question I like to reference the amazing work from the OWASP foundation ;)
For Web Apps
OWASP Web Top 10 Risks
The OWASP Top 10 is a powerful awareness document for web application security. It represents a broad consensus about the most critical security risks to web applications. Project members include a variety of security experts from around the world who have shared their expertise to produce this list.
The Web Security Testing Guide:
The OWASP Web Security Testing Guide includes a "best practice" penetration testing framework which users can implement in their own organizations and a "low level" penetration testing guide that describes techniques for testing most common web application and web service security issues.
For Mobile Apps
OWASP Mobile Security Project - Top 10 risks
The OWASP Mobile Security Project is a centralized resource intended to give developers and security teams the resources they need to build and maintain secure mobile applications. Through the project, our goal is to classify mobile security risks and provide developmental controls to reduce their impact or likelihood of exploitation.
OWASP - Mobile Security Testing Guide:
The Mobile Security Testing Guide (MSTG) is a comprehensive manual for mobile app security development, testing and reverse engineering.
For APIS
OWASP API Security Top 10
The OWASP API Security Project seeks to provide value to software developers and security assessors by underscoring the potential risks in insecure APIs, and illustrating how these risks may be mitigated. In order to facilitate this goal, the OWASP API Security Project will create and maintain a Top 10 API Security Risks document, as well as a documentation portal for best practices when creating or assessing APIs.
I think instead of detecting whether the request comes from Postman, it is better for you to protect the endpoint with authentication.
With this, even tho the user submitted a request through postman, you can still make sure that it is the user itself who made the request.
Please do let me know if there are actually other concerns bothering you. Cheers :)

How to allow API call only from the same origin/ domain?

So I have run into a problem. I am building a javacript file, which appends an iframe into clients page (within a div). Lets say, this iframe is loaded from http://example.com/iframe. iframe's backend module (to handle form submission; written in spring) has some endpoints like http://example.com/url1, http://example.com/url2
Now, I want only the iframe to be able to communicate with backend APIs. Currently, I can hit the iframe backend APIs from localmachine too.
I have come across the referer HTTP field, and initially was planning to set a referer filter on the APIs, but later found out that this can easily be spoofed. Will I get any benifit sertting CORS header on the APIs and setting the origin as http://example.com? Will it work, and if yes, is this a safe and dependable solution? Are there any better alternatives?

JSONP question for making PUT/POST/DELETE cross-domain requests

I've created a RESTful API that supports GET/POST/PUT/DELETE requests. Now I want my API to have a Javascript client library, and I thought to use JSONP to bypass the cross-domain policy. That works, but of course only for GET requests.
So I started thinking how to implement such a thing and at the same time trying to make it painless to use.
I thought to edit my API implementation and check every HTTP request. If it's a JSONP requests (it has a "callback" parameter in the querystring) I force every API method to be executed by a GET request, even if it should be called by other methods like POST or DELETE.
This is not a RESTful approach to the problem, but it works. What do you think?
Maybe another solution could be to dynamically generate an IFrame to send non-GET requests. Any tips?
There's some relevant points on a pretty similar question here...
JSONP Implications with true REST
The cross-domain restrictions are there for a reason ;-)
Jsonp allows you to expose a limited, safe, read-only view of the API to cross domain access - if you subvert that then you're potentially opening up a huge security hole - malicious websites can make destructive calls to your API simply by including an image with an href pointing to the right part of the API
Having your webapp expose certain functionality accessed through iframes, where all the ajax occurs within the context of your webapp's domain is definitely the safer choice. Even then you still need to take CSRF into consideration. (Take a look at Django's latest security announcement on the Django blog for a prime example - as of a release this week all javascript calls to a Django webapp must be CSRF validated by default)
The Iframe hack is not working anymore on recent browsers, do not use it anymore (source : http://jquery-howto.blogspot.de/2013/09/jquery-cross-domain-ajax-request.html)

Does requiring POST plus custom Content-Type prevent CSRF?

My team is building a site that uses AJAX calls to WCF services for all state changes. Those services only accept a request if its method is POST and its Content-Type is 'application/json'. Assuming that our site has no XSS vulnerabilities, is this sufficient protection against CSRF for our WCF services? Is it possible for an attacker to create a cross-site POST with a custom Content-Type header?
[EDIT]
Obviously there are several ways for a malicious third party site to construct an HTTP POST request to my site. As far as I am aware, however, none of these methods allow for changing the Content-Type header. XHR and Flash both let you set headers, but have strict cross-site restrictions.
Probably, but why not go ahead and check the HTTP Referrer header? Then you will know for sure.

Resources