Protecting contents against download and against unauthorized users - iis-8

I have a content delivery server where I keep a variety of file types such as HTML, Video, Audio, Image, etc. I have done this by just creating a website in IIS with no code (No ASP.Net, PHP, etc), and yeah just a blank website in which I have copied my files. Alongside with this server, I have a web server which is fully distinct and it has been written using ASP.Net Core and it is responsible for authenticating users, delivering pages, etc.
The problem is that the content preserved in that CDN is unprotected and now, any user can request those materials. With respect to the fact that I have no code in there, is there any way to define to IIS to only authorize request which have a valid authorization token in their headers? (how to validate the header is another problem)

Related

redirect uri different for each user in OAuth 2.0 (dynamic redirect uri)?

We have a public API that supports OAuth 2.0 server and client flow. Per OAuth 2.0 spec, https://www.rfc-editor.org/rfc/rfc6749, each integration application will have 1 application key and users using that application will authorize that application for API access of user's data.
Things worked fine until we find application developers suggesting their users to create one application key each as users will all have their own redirect uri. Put aside the false API usage information it creates, we are seeing a big increase in application key creations that is not tolerated by our API agency.
I am wondering if we can suggest such application developers to add an extra layer for redirect between our oauth server and their users' redirect uri. So their application key will be created with a redirect uri that actually loads a page created by their application, then redirects to the user's specific redirect uri, which is inputted at the user's registration.
Hope I explain it well. I am wondering whether this exposes any more security vulnerabilities than it already has. My point is someone has to do the redirect anyways, rather than we do it with all the unnecessary extra information involved, we'd like to let our client applications take control of it.
Any suggestions/hints/clues/ideas are deeply appreciated.

Access-Control-Allow-Origin issue on BulkSMS

I am using Angular 5 to send post request to send SMS through Bulksms : http://bulksms.com/
When making the request from Angular (client), I am facing this issue :
Origin http://TTTT:4200 is not allowed by Access-Control-Allow-Origin.
How can I correct this issue in BulkSMS ?
Regards,
Your browser's same-origin policy is restricting your Javascript code from accessing a third party (i.e. api.bulksms.com in this case) in the way in which you hoped to do it - and CORS (Cross-Origin Resource Sharing), which is a mechanism to relax those restrictions, is not relaxed enough to allow these requests (from you as an untrusted third party) either.
Wikipedia Same-origin policy : "Under the [same-origin] policy, a web browser permits scripts contained in a first web page to access data in a second web page, but only if both web pages have the same origin. An origin is defined as a combination of URI scheme, host name, and port number. This policy prevents a malicious script on one page from obtaining access to sensitive data on another web page". The Wikipedia page contains some good examples of the sorts of malicious Javascript code uses that the same-origin policy tries to limit.
It is important to note that these restrictions are only enforced by browsers: HTTP client code that is not running under a browser typically doesn't care about any of this.
For development purposes, there are some tools that can make your life easier - for example, you could use live-server to run a simple HTTP server which serves up your static files, while also using its --proxy option to route requests to api.bulksms.com and solve your same-origin policy problem in the process.
For production, a typical solution is to route your AJAX requests, which are destined for the third party service, via your own server (the one serving up your Javascript files to your browser), or a reverse proxy (which would front both your own and the third party service). If there is a server side to your application, you can make the HTTP requests to api.bulksms.com from there, using an HTTP client, and then have your Javascript code talk to your own server, to indirectly make the requests to bulksms.com. This also gives you the opportunity to add authentication headers on your server side, without your Javascript code ever having to know them (e.g. if you have one bulksms.com account, and many users able to use that account via your Angular app, but who should not know your credentials). Similarly, you could impose limits on what your Angular users can do in this way (e.g. to limit the number of SMSs they could each send per day).

Set or Get cookies for different domains (not on a subdomain)

I have a file server, or more of a personal CDN, which I want to protect against unauthorized access. Assuming that this personal CDN is accessible through https://www.personalCDN.com, and the requests to this file server come from the following domains:
1- https://www.Application1.com
2- https://www.Application2.com
3- https://www.WebSite1.com
In case I want the authentication layer to be cookie-based in a way that, when the user logs into any of these three domains, a cookie for https://www.personalCDN.com would be added to browser, and then it would be used by the main file server, how can I handle this situation in ASP.Net Core 2.x? I've read that, writing cookies for other domains is not allowed in JavaScript, does it apply to Asp.Net as well?
It's not a JavaScript limitation, it's a functional limitation, in general. Cookies are domain-bound. They can only be written on the domain where the response originates. Likewise, a cookie can only be read by the domain that set it. This is for security reasons, and there's absolute no way around it.
What you would need is a SSO (single sign on) solution, which is not a trivial thing to set up. You essentially have one server that acts as the auth gateway. Your other websites redirect users to that server to login, the user logs in on the auth gateway, where a cookie is set for that domain (i.e. auth.domain.com). This keeps the user logged in on the gateway. Then, the user is redirected back to the originating site, with a token. That token is then validated via an API backchannel to the auth gateway. If the token is valid, then the originating website "logs in" the user, setting a cookie for its domain, as well. Rinse and repeat with all your other websites.
For something like your CDN, you would likely need a site hosted on a subdomain of that same domain (since the CDN itself wouldn't be able to coordinate the auth process). That site, then, would set a wildcard domain cookie, which would be usable by the CDN as well.
You can either set up all this infrastructure yourself (not recommended), or there's third-party libraries like IdentityServer that could ease implementation. Additionally, you can outsource the whole shebang to a third-party provider like Auth0, where it essentially becomes your gateway.

How can I share Azure Active Directory authentication between server side and client script?

I currently have an MVC app that's using the Microsoft.Owin.Security.WSFederation package for authentication with Azure's Active Directory. This lets me use the Authorize attribute on my controllers to redirect users to the Microsoft login site.
I now have the requirement to add access to a WebAPI project that will be hosted on a different domain but will use the same AD store.
I've managed to pull together something using the ADAL JS library provided by Azure but this gives the following process:
user visits site and is redirected to Azure login
user logs in and is returned to site
JS code checks for login and redirects to Azure
user is already authenticated so redirects back to site with token
JS picks up token, stores it, and redirects to the original page
So it works, but involves 4 redirects, which seems like a huge overhead.
I thought that there might be some way of pulling a bearer token out of the authorisation credentials returned when the WSFederation succeeds but I can't see anything like that in the data. And, even if I could, I don't know how I'd be able to then refresh the token from the client script. So I strongly suspect I'm doing something fundamentally wrong.
What would be the best process for sharing authentication between the two sites?

Offer some REST API resources for specified clients

I think there is no solution for problem we're facing, but for confirmation I would like to you ask here.
We have REST API that is consumed from:
administration website (AngularJS)
customer website (AngularJS)
other REST API clients (own API applications)
Because requests from administration/customer website are made by AngularJS at a client side, users are able to determine (e.g. via FireBug) resources URLs and are able to consume all these resources from their own applications - what we don't want to and we cannot to restrict it e.g. with IP address because requests go from client. We would like to offer some group of resources only for customer / administration website and some resources for own REST API clients and some resources for both, but from the principle of JS requests made from AngularJS (and resource URL visibility) it cannot be done(?).
What could be the best practice for this issue?
Note: Your REST resources should always be secure. You should never depend on any client side javascript code. If your security is breached because someone knows the URI of an REST api; something is very wrong.
Angular can be made modular is such a way that the customers only see the customer modules and the administrators see the customer and administrator modules. This way you can let the administrators play in a WYSIWYG environment without having them to switch back and forth between the websites.
// Customers.js
// Module only containing customer code
angular.module('myCustomerProducts', ['myMainApp']);
// Administrators.js
// Module only containing administrator code
angular.module('myEditCustomerProducts', ['myCustomerProducts', 'myMainApp']);
Since your website is already separated for administrators and customers you can simply only include and deploy the javascript code for the specified target site. If this is not the case you'll need some server side transformation (eg. ASP.NET, PHP, Jade, ...) to build the index.html dynamically based on the credentials of the user.
Depending on the hosting platform, you can also deny access to everyone not in the administrator group when requesting anything from the administrator website (area).
But again; the server side security is way more of value. You can't secure an insecure server with javascript (on the client side).