Google Analytics with Silverlight HTTPS cross domain policy problems - silverlight

I'm sending simple messages to Google Analytics from a Silverlight app. They look something like this (data changed):
http://www.google-analytics.com/collect?v=1&tid=foobar&cid=foobar&t=pageview&dp=foobar&dt=foobar
Very simple API. If I use HTTP it works beautifully.
If I use HTTPS, I run afoul of Silverlight's cross domain policies. According to the docs, google-analytics.com needs to approve the cross-domain call by hosting either a clientaccesspolicy.xml (Silverlight-specific) or crossdomain.xml (original used by FLASH). Turns out they do host crossdomain.xml, and I can see that Silverlight downloads it (via Fiddler), but apparently Silverlight doesn't like the file's content and doesn't allow HTTPS calls to that domain (System.Security.SecurityException).
So.. at least at the moment, I can't use Google Analytics from Silverlight using HTTPS. Does anyone know a work around for this issue?
Note, I can't just use HTTP, because that causes IE to issue a "Allow Mixed Content" prompt which causes problems for some of our customers. I need to use HTTPS like the rest of our app.
EDIT: OK, I took a totally different approach, using HtmlPage.Window.Invoke to call a 3 line Javascript function to do the asynchronous send rather than using WebClient in the Silverlight code. Works like a champ. Anybody see any potential problems with that?

I suspect there may be a way to make this work, because I know google-analytics.com is very cross-domain friendly for exactly this reason.
If you absolutely can't get it to work another option would be to proxy the hits. If you do this, you'll want to make sure to use the ua and uip override fields in the hit you're sending so that they show up in Google Analytics with the IP address and User Agent of the original visitor and not your server.
Here's some more info on using a proxy server with the Measurement Protocol:
https://developers.google.com/analytics/devguides/collection/protocol/v1/devguide#using-a-proxy-server

Related

Securing a Google App Engine service deployed in Node/Java against a scripting attack

I have an app engine service deployed in GAE (written in Node) to accept a series of click stream events from my website. The data is pushed as an CORS ajax call. I think, since the POST request can be seen in browser through the developer tools, somebody can use the app engine URL to post similar data from the browser console.( like in firefox, we can resend the URL. Chrome also has this features i guess)
A few options I see here is,
Use the firewall setting to allow only my domain to send data to the GAE.
This can still fail me since the requests can be made from the browser console repetitively)
Use a WAF ( Web Application Firewall) as a proxy to create some custom rule.
What should be my approach to secure my GAE service?
I don't think the #1 approach would actually work for you: if the post requests are visible in the browser's development tools it means they're actually made by the client, not by your website, so you can't actually use firewall rules to secure them.
Since requests are coming into the service after fundamentally originating on your own website/app (where I imagine the clicks in the mentioned sequences happen) I'd place the sanity check inside that website/app (where you already have a lot more context info available to make decisions) rather than in the service itself (where, at best, you'd have to go through loops to discover/restore the original context required to make intelligent decisions). Of course, this assumes that the website/app is not a static/dumb site and has some level of intelligence.
For example, for the case using browser development tools for replaying post requests you described - the website app could have some 'executed' flag attached to the respective request, set on the first invocation (when the external service is also triggered) and could thus simply reject any subsequent cloned/copy of the request.
With the above in place I'd then replace sending the service request from the client. Instead I'd use your website/app to create and make the service request instead, after passing through the above-mentioned sanity checks. This is almost trivial to secure with simple firewall rules - valid requests can only come in from your website/app, not from the clients. I suspect this is closer to what you had in mind when you listed the #1 approach.

Evernote Resource URLs

I'm writing an application that takes a user's Evernote notes and displays them in a website inline. By its very nature, people accessing the resources attached to a note will not be logged in. I'm looking at the bottom of this page and saw how to pass authentication credentials via POST and get the resource. This is exactly what I need.
My question is how does this work in the real world? If I pass authentication tokens to the Javascript client (not secure in the first place), I can't get the resource because of Access-Control-Allow-Origin restrictions. The only other way I can think of doing this is saving all of the resources to my server and serving them from there, but that's not ideal (Google App Engine).
Ideas?
Yea, Evernote does not support CORS yet. You can do it in a chrome extension or get it on the server side.

Why can't I make a WebRequest to a secondary domain from Silverlight?

I have an 3rd Party API I'm wanting to use from my Silverlight 4 Application. It's interface is simply a web request (NOT A WEB SERVICE!) with form variables. According to everything I've read, this is not possible because of security issues? What security issues? Is there no way to do this? I can understand not allowing this with web services, but with simple web requests?
I cannot use my RIA Services gateway because the data is VERY sensitive and I cannot (and do not want to) transmit it under my own SSL cert. This is RIDICULOUS!
The same security issues apply in Adobe Flash. In JavaScript, it's not possible at all.
For Silverlight, the website root must contain a clientaccesspolicy.xml permitting the call.
http://msdn.microsoft.com/en-us/library/cc197955%28v=vs.95%29.aspx
To stop Cross Site Request Forgery (XSRF). Without this measure, what's to stop an attacker from issuing requests to online banking sites (or any site) on the users behalf? Exploiting the fact he may have cookies stored which will allow the request to go through.
It's too bad the internet has turned into an assumed guilty until proven innocent situation, as I could see many useful, non-malicious, uses for sending web requests.

how to limit access to a silverlight-enabled data service?

We have a Silverlight app which we wrote which calls a Silverlight-enabled data service. The Silverlight app cannot require a login, as it is required to present data to the unauthenticated public.
We have some schmoe who took the time to examine our Silverlight app, one way or another figure out what service it is calling, and then wrote his own client to slurp off the data so he can post it on his site and pretend like it is his. We need to prevent this.
How can i limit my data service somehow to ONLY accept requests from my silverlight app? I tried using the allow-from domain uri setting in the clientaccesspolicy.xml file to limit access to the service only from the domain in which the silverlight app sits (say mydomain.com). This did absolutely nothing though, and the service is still serving up requests to clients from outside the domain. (I tested this by putting my SL app on a different domain under our control).
What is the proper/best/most effective way to limit the data service so only our app can use it? Thanks!!!
I'm using SL 3 and .NET 3.5.
The clientaccesspolicy.xml tells the Silverlight application which Webservice it can consume. Not preventing people accessing the Webservice.
You can try using a authentication login even though its not required. This prevents 'schmoes' accessing your webservice.
Also use Dotfuscator to prevent 'schoes' to disassemble your Silverlight application and acquire the login.
Silverlight webservice security follows the same patterns you'd use for ASP.NET security, especially services exposed to AJAX. The best way to do make use of ASP.NET's authentication.
RIA Services is an even better way to handle this. It rides on top of the ASP.NET authorization, but validates on both the client and server-side automatically to combat service spoofing. It let you take care of both client and server-side authorization by adding attributes to your methods indicating that the method requires authorized access, and by which groups or users if you need to be specific.
In addition to wire-side security and obfuscation, remember that clients can attach a debugger to Silverlight applications running in their browser. See this example from MSDN Magazine's Security IQ Test, November 2008.

Many Custom Domains for AppEngine Instance

For our e-commerce service running on AppEngine we would like to offer the option for customers to run the stores on their custom domains (eg: www.mystore.com instead of www.enstore.com/mystore).
From a user perspective, I'd like them to enter the domain name they want to use in their preference screen and tell them how to configure their dns.
I know how you normally add domains to an AppEngine instance (through Google Apps) but I'm not sure you can automate that. And even if that's possible they would be all (hundreds) listed on our google apps page.
Anyone know if this is possible/if there is a good way to do it?
I don't think there is a way to add domains "programatically" to an AppEngine instance. Apparently, domains can only be added by using the Google Apps method that you described. This is confirmed in this SO post: How do i get foo.somedomain.com get handled by myapp.appspot.com/foo on appengine
The only options that pop to mind are the following:
HTTP Redirection
Many DNS providers support HTTP Redirection. In this case, your clients would be able to set up mystore.com and www.mystore.com to redirect to www.enstore.com/mystore. There are some obvious disadvantages with this method that might not be acceptable. First of all, with 301 and 302 redirects, the users will still be forwarded to the registered AppEngine URL: www.enstore.com/mystore, and it will show in their browser. In addition, choosing between a 301 and 302 redirect can make SEO tricky, since you'd have to get into how search engines behave with these redirects. For example most search engines will not use the original URL as a source for keywords when you use a 301 redirect.
In addition to 301 and 302 redirects, some DNS providers (like DNS Made Easy) also provide what they call a "masked hidden-iframe redirect". The page will render inside a hidden iframe, so the URL does not change in the user's browsers. However this makes SEO even more tricky, and it will not allow users to bookmark internal pages, or to reference them easily.
As you can see, this option is less than ideal, but it is one option to consider in some situations. Also note that at the moment, HTTP Redirection using 301 redirects is the suggested workaround for the Naked Domain Issue 777 on the AppEngine issue tracker.
Reverse Proxy
Another option could be to set up a small server somewhere else, like a small Amazon EC2 Instance, and set up a simple reverse proxy. You would be able to set this up very easily, just by using Apache and mod_proxy (or various other alternatives). This would allow you to ask your clients to set up a normal A Record pointing to this instance, while the Apache HTTP server would be acting as a proxy to your AppEngine.
The fundamental configuration directive to set up a reverse proxy in mod_proxy is the ProxyPass. You would typically set it up with one line like these for each VirtualHost (for each client domain):
ProxyPass / http://www.enmystore.com/mystore/
The configuration of the remote proxy could be easily handled by your back-end software.
This is a neater solution which gives you plenty of control - but there are obviously some costs for these benefits. First of all, there is the expense to host the reverse proxy. You would also be adding another point of failure, so you have to add this to your high-availability plan. In addition, if you are serving some pages through SSL it can become quite complicated.
Another option is to have each customer sign up for google apps, and then add your appengine app to their app. That way they can manage the url. They will need to use a cname for this, so urls will be limited to something like 'store.customer.com' You will have to support the multitenancy off of the host-header, but that isn't hard to do given that you already have a way to support multitenancy already. You might want to do the setup for the first couple of clients yourself so you can document the easiest way to set it up.
The rietveld code review app does this as you can add it to your google apps domain. See http://code.google.com/p/rietveld/wiki/CodeReviewHelp#Using_Code_Reviews_with_Google_Apps for more detail.
The preferred option is probably to offer your solution through the Google Solutions Marketplace: http://www.google.com/enterprise/enterprise_marketplace/about.html
We did something similar to Daniel Vassallo second proposal.
We created a python app on the Heroku cloud
(there is no limit for connecting custom domains).
This app is using python requests 1.2.0 lib to get the correct page from your app engine application according to the request domain.
all you need to tell your clients is to put your Heroku app url as their CNAME
For naked domains you can always use wwwizer

Resources