How to restrict a Flex application to only run from my website? - apache-flex

is it possible to make a Flex-application to only run from my domain? So a user can't copy the .swf and start it locally.

In a lot of cases this won't work because of the security model associated with the crossdomain.xml.
http://www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html
Say for example, I have a flex app that has a service call and login to my backend database (perhaps PHP and mysql). Unless I explicitly enable it in crossdomain.xml policy file the app will not be able to communicate with my server unless the swf file is directly loaded from my domain. If the app was local it would look to my server like localhost was trying to access my backend through the flex app. So by default this would not work unless an explicit rule was put in place in the crossdomain.xml to allow access from localhost. Likewise someone cannot simply put the swf on a different server and try to access from my server unless I add that remote server to the crossdomain.xml policy.
So back to your question. Obviously, this crossdomain.xml stuff doesn't really apply if your flex app is really simple and does not try to make service calls to a server. For example, if you have simple game that just loads and plays without additional server calls inside the flex game.
If you wanted to protect your app you could have a basic "phone home" process during the startup sequence that makes a very simple server call to your website. It doesn't have to be anything super complicated, just require a round trip service call in the start up of your app. Perhaps check for a simple key or string stored in a variable on the PHP side, and don't let the flex app run unless that key is valid. You could hardcode the expected key inside the actionscript. Or perhaps have a basic logger that tracks how many times the app is launched and store the count in a database or something. The main thing is do not let the app completely launch until this request to the server has returned a valid result.
If you have this in place then the crossdomain.xml policies will kick in and if someone downloads your swf it shouldn't work because it will try to make a call from localhost to your server. Or if they steal your app and host it on their site it shouldn't work either.

The simplest solution il probably to check the value of
Application.application.loaderInfo.url
on application startup (for example in the applicationComplete event) and match it with your web site domain.

Do check out flash.System.Capabilities.playerType on LiveDocs as well.

Related

asp.net application intermittently fetching the old values from updated web.config in IE

I have an MVC4 application hosted on IIS in my local system. The application provides the search capabilities by using various Searchblox API. I have stored the host server value in my web.config. Now while my application is running and I change my host value say from "https://xyz" to "https://abc" in my config then for some places the correct value is fetched but for one call the old "https://xyz" is fetched.
I perform the below steps in sequence:-
Hit my application page from IE.
App executes successfully.
Open Web.config in VS to switch the host value.
Save the config file. (Now as per my knowledge this should have restarted the appdomian consisting my app and should have brought the new value)
Hit my application again in IE.
Watch the internal calls in Fiddler. All API calls are now made to new "https://abc" but one call is made to "https://xyz".
This behavior works fine if I recycle the Apppool containing my application.
Someone, please explain why this might be happening and how can I make sure that my application always pick the new values for every call?
This was happening because we were caching the previous host value in order to use it if the new changed host API fails to establish a connection. This was completely app specific.

Do I need to do anything different with the client or is it a server setting that needs modification?

I have a Flex based application which is using Flash Media Server (FMS) server (version 4.0) for live video streaming between two users (i.e. a one to one teleconferencing service). This streaming is one-to-one, as defined by business rules, so that no third person can join a teleconference. Either person can start the video stream via a browser-based Flex client and communication gets established once the second user joins. Validation for connecting the streams of the two users is implemented on the FMS server (as server side scripting defined in main.asc). I am facing three critical problems with our teleconferencing solution.
1.Often times, full communication can not be established between the two users. One user can not usually see or hear the other user. There is a client side 'refresh' button that when clicked, attempts to establish a connection via the server side script. This sometimes works. Before implementing our current server side script, I tried establishing a stream by using methods found here: http://forums.adobe.com/thread/905613
I think the method below may work as it would give me an array of subscribers to the stream.
getLiveStreamStats(appInst:String, stream:String) : Object
But the problem is that server returns the following:
<level>error</level>
<code>Admin.API.MethodNotAllowed</code>
<description>getlivestreams - Method not allowed!</description>
<timestamp>8/7/2012 10:05:38 AM</timestamp>
Question - Do I need to do anything different with the client or is it a server setting that needs modification?
You didn't specify if you were making the remote calls using HTTP or RMTP. If you're using RMTP you shouldn't have to do anything. If you're using HTTP you will need to modify the following files:
{Flash/Adobe Media Server Root}\conf\AMS.ini (or FMS.ini if you're on an older version)
{Flash/Adobe Media Server Root}\conf\Users.xml
In the first, you will need to set the USERS.HTTPCOMMAND_ALLOW option to true. In my version of the AMS.ini file it is at the very bottom of the configuration page.
In the Users.xml file, you will need to locate the block. In my version, this is also located towards the bottom of the page. The default install of Adobe Media Server 5 (in my case anyways) only allowed the "ping" method and all other methods were disallowed. You will either need to update that block to reflect a comma-delimited list of the methods you want to make accessible via HTTP (white listing) or allow all and deny none (I wouldn't recommend that).
Don't rely on a soft restart of the Adobe/Flash Media Server via the web based Administration Console. This did not work for me. I needed to restart the AMS service from within the Windows Services panel in order for the changes made in the configuration files to take effect.
I hope that this helps!
Rick

How to invoke code within a web app that isn't externally open?

Say, for example, you are caching data within your ASP.NET web app that isn't often updated. You have another process running outside of the app which ocassionally updates this data, when you do this you would like the cached data to be cleared immediately so that the next request picks up the new data straight away.
The caching service is running in the context of your web app and not externally - what is a good method of calling into the web app to get it to update the cache?
You could of course, just hack a page or web service together called ClearTheCache that does it. This can then be called by your other process. Of course you don't want this process to be externally useable or visible on your web app, so perhaps you could then check that incoming requests to this page are calling localhost, if not throw a 404. Is this acceptable? Could this be spoofed at all (for instance if you used HttpApplication.Request.Url.Host)?
I can think of many different ways to go about this, mainly revolving around creating a page or web service and limiting requests to it somehow, but I'm not sure any are particularly elegant. Neither do I like the idea of the web app routinely polling out to another service to check if it needs to execute something, I'd really like a PUSH solution.
Note: The caching scenario is just an example, I could use out-of-process caching here if needed. The question is really concentrating on invoking code, for any given reason, within a web app externally but in a controlled context.
Don't worry about the limiting to localhost, you may want to push from a different server in future. Instead share a key (asymmetrical or symmetrical doesn't really matter) between the two, have the PUSH service encrypt a block of data (control data for example) and have the receiver decrypt. If the block decrypts correctly and the data is readable you can safely assume that only the service that was supposed to call you has and you can perform the required actions! Not the neatest solution, but allows you to scale beyond a single server.
EDIT
Having said that an asymmetrical key would be better, have the PUSH service hold the private part and the website the public part.
EDIT 2
Have the PUSH service put the date/time it generated the cipher text into the data block, then the client can be sure that a replay attack hasn't taken place by ensuring the date/time is within an acceptable time period (say a minute).
Consider an external caching mechanism like EL's caching block, which would be available to both the web and the service, or a file to cache data to.
HTH.

How to detect all the browsers that are installed in a system?

Hi guys how to detect all the browsers that are installed in a system.By using Flex
You cannot do that from Flex or, as far as I can tell, from any web application. A web app being able to go through the list of installed applications on client machine is bad from a privacy and security point of view.
Maximum you can do is to read the user agent string from the HTTP headers (which can be easily modified and hence need not be accurate) to check what's the current browser being used to access your application. Even this, you can't do from Flex, you'll have to do it using some server script and send the information to the Flex app.
#Amargosh, while you do have to go through the server page to get client information, you can simply get browser information by executing Javascript from Flex:
var result:String = ExternalInterface.call("eval", "navigator.userAgent");
This will do the trick.

Who is calling my WebService?

I have a web service that is on an internal server. It can be called from any website on our network.
More and more developers are starting to use it. Current probably 20+ pages use this service, and the number is growing fast. I can see a year from now, someone asking what pages are using this service and what methods.
I would like to log the url of the pages that use my web service as the request come in.
It would also be nice to know the method they are calling.I need to do something in such a way, that it does not affect the client web sites.My first thought was that I could write some code in the global.asax.
I have added some code to the Application_BeginRequest to log the request object details, but there does not appear to be anything about the requesting url.
What am I missing? Should I be looking at a different object?
Thanks.
Without disrupting existing users this is going to be difficult. The httpContect.Current.RequestUrl will just return the URL used to call your web service, not which web page called it.
The closest you can do without disrupting existing apps and forcing developers to change them is to grab the HttpContext.Current.Request.UserHostAddress, so you can at least get the IP of the machine calling your service.
Beyond this, what you might want to consider is adding a parameter to your functions for "CallingApp" and then log that in your code. That's pretty much what we did once re realized that we needed to know which apps are calling our service. We actually have an application monitoring service that uses a GUID for every new app we develop, and we pass that GUID to any web service. It[s extra work but to us it was critical because it allows us to know which apps will be affected when we need to perform updates or take the app server down for maintenance.
Edit - added
As a side note, at the point we realized we needed to track this, we had already been using web services for about a year. When faced with the same problem, we created a new set of web services, and included the extra field for the calling app in all of the new services, and then slowly went back and changed the older programs to point to the new services.
IN retrospect, we wish we had known we would need to do this up front because it created a lot of extra work. I'm guessing you'll be facing something similar if you really want to know exactly who is calling your services.
The only thing you can probably retrieve from the consumer is the IP address without changing your interface.
If you can change this you could do this e.g. by adding authentication and logging who is calling what, or by having some simple "token" principle.
However both methods require you to change the interface and therefore break backwards compatibility - which you should never do.
By always ensuring both back and forward compatibility you should not need to know exactly who is calling your service, but only that it is actually used.
#David Stratton
Thanks for your help. I think your suggestions were great. I accually did something very different, after your answer gave me some new ideas.
I should have mentioned that I was generating the web proxy that most of my users were using to make calls against my web service. My client in general do NOT use the proxy that Visual Studio creates.
Here is what did:
I generated my web proxy client again, and added calls to log the httpcontext of the client before every call. Because the proxy is running on the client, he had access to everything I needed. That allowed me to record everything about the client and the specific call they were making. I realize this would not work for most cases. But all of my clients are internal web sites.
It also had the advantage in that the clients did not have to modify their code at all. I just gave them all a new DLL. Problem solved. I get all the tracking data I want, and they did not have to modify their code.
I was stuck trying to solve the problem from the web service's point of view.
I realize that there is still a whole in this implementation, because someone does not have to use my client proxy to call my service. I guess I could force that at some point in the future. For now, they could let Visual Studio genereate a web proxy for my service. However, if they do that I guess I don't care. That is not the recommened way to call my service. I think the only one doing that is an ASP.NET 1.1 web site. When they upgrade, they will probably switch to my generated proxy.
Without implementing some sort of authentication, there isn't a guraenteeted way of knowing exactly who is calling your service - web metrics are the only way you can gauge what volume of traffic is hitting your service.
I'm sure you already know this but the whole point of a web service isn't to know or care who is calling it.
I have successfully used ...
Dim strReferrer As String = HttpContext.Current.Request.UrlReferrer.AbsoluteUri
to get the calling page that called my WEB API 2 Web Service.

Resources