Detecting a redirect in Flash/Actionscript? - apache-flex

I have a flash video player which requests a flv file from a central server. That server might redirect the request to a server from the user's country if possible, a lot like a CDN.
This video player also reports usage stats. One thing I'd like to report is the true server/location from which the player is streaming the video from. So basically, if it gets redirected I want to know about it.
It seems that you can't extract the url from a URLLoader, you can only keep a copy of the URLRequest that you constructed it with.
I notice that you can listen for HTTP status events, which would include a 302 or similar. But unfortunately, the HTTPStatusEvent object doesn't show the redirected location.
Any ideas about how to monitor for a redirect, and get the redirected location?

I'm a bit surprised Flash allows you to redirect a video request at all. I did a bit of digging and it looks like you can get the info:
Handling Crossdomain.xml and 302 Redirects Using NetStream
His post specifically talks about the trouble of security issues that arise because of the fact some operations fail if data is from an untrusted server. Since he doesn't know where his video is coming from (302 redirect) the Flash Player doesn't trust it and prevents some operations on the loaded content.
How he gets the server the content was actually loaded from is to do an operation on the file that should not be allowed and he parses the domain information from the error message:
try
{
var bit:BitmapData = new BitmapData(progressiveVideoPlayer.measuredWidth, progressiveVideoPlayer.measuredHeight, false, 0x000000);
bit.draw(progressiveVideoPlayer);
}
catch(error:SecurityError)
{
var list:Array = error.toString().split(" ");
var swfURL:String = list[7] as String;
var domain:String = list[10] as String;
domain = domain.substring(0, domain.length - 1);
var domainList:Array = domain.split("/");
var protocol:String = domainList[0] as String;
var address:String = domainList[2];
var policyFileURL:String = protocol + "//" + address + "/crossdomain.xml";
Security.loadPolicyFile(policyFileURL);
}
Notice he is doing it so that he can load the policy file (to allow the security restricted operations on the file). I'm not sure it will be helpful to you but at least read the article and have a think about it. You may contact the blog author directly too - he is pretty active in the general Flash community.

Related

Getting storage item without CORS configured

I fetched an item from my Firebase storage bucket via this technique (generally):
const url = await firebase.storage().ref('my/ref').getDownloadURL();
const filename = 'filename.ext';
const a = document.getElementById('link');
a.href = url;
a.download = filename;
a.click();
I did it the above way prior to trying the example from the docs:
storageRef.child('images/stars.jpg').getDownloadURL().then(function(url) {
// `url` is the download URL for 'images/stars.jpg'
// This can be downloaded directly:
var xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.onload = function(event) {
var blob = xhr.response;
};
xhr.open('GET', url);
xhr.send();
});
When trying it this way, I hit the CORS error. After adding the CORS config to my bucket, it then worked as expected. However, I cannot determine why I was able to successfully fetch it via the first technique prior to configuring CORS.
I tested it again by removing the GET method from my CORS config and uploading the config file again via gsutil. I was still able to successfully obtain the file via the first technique described above.
If this is possible to do without configuring CORS, how can I prevent it to restrict access? Odds are no one will be able to figure out the required ref to build the link, anyways, because the actual ref has multiple unique IDs that will be all but impossible to figure out. This is mainly a question out of curiosity.
I cannot determine why I was able to successfully fetch it via the first technique prior to configuring CORS.
Because same-origin policy doesn't apply when the Javascript can't access the data. In your first example, the JS tweaks the document and the document accesses the data. In the second example, the JS accesses the cross-origin data, and the absence of CORS prevents such access.
If this is possible to do without configuring CORS, how can I prevent it to restrict access?
CORS isn't designed to restrict access. (Wait, what?) CORS is designed to permit access that would otherwise be assumed to be something the user would not want -- for scripts on one page to have access to data from another origin, including, potentially, handing over use of the user's credentials to scripts on the current page when accessing the foreign site. CORS allows site B to tell the browser that it expects to be contacted by scripts from site A, and therefore such access should not be unexpected or assumed unauthorized. It has no impact on requests that don't fall under the same origin policy.
The solution -- and I apologize if I am stating the patently obvious -- is that getDownloadUrl() should not be able to fetch a usable URL for the object, if the object should not in fact be accessible. You can't trust code running on the browser, so whatever credentials are in play here should not be able to be used in this way, if the object is not intended to be accessible... otherwise you have a misconfiguration that is allowing access that should not be allowed.

Http request command line tool

I am developing a Command Line Tool in Swift 3, i have this code:
let url = "www.google.com"
var request = URLRequest(url:url)
request.httpMethod = "GET"
let task = session.dataTask(with: a){ (data,response,error) in
print("REACHED")
handler(response,data)
}
task.resume()
I cannot reach the task if i use "http://" or "https://" as prefix in any url, i am wondering if i need a App Transport Security plist, i already tried create a simple plist, anyone knows some if has a particularity for this problem?
When specifying a URL, you need the "scheme" (e.g. http:// or https://).
The url is a URL, not a String, so it should be:
let url = URL(string: "http://www.google.com")!
Yes, you need Info.plist entry if you want to use http://. E.g. https://stackoverflow.com/a/37552442/1271826 or Transport security has blocked a cleartext HTTP or just search stack overflow for "[ios] http info.plist" or with [osx].
Note, in Xcode 8.1, console apps don't necessarily have a Info.plist file, so if you don't have one, you may have to add one by pressing command+n:
update your target settings to specify the plist:
and then add the appropriate settings, e.g.:
I assume where you have URLRequest(with: a) you meant URLRequest(with: request).
You'll need something to keep the command app alive while you're performing the request (e.g. a semaphore or something like that).

Failed to load resource: net::ERR_INSECURE_RESPONSE

IS there a way to trick the server so I don't get this error:
Content was blocked because it was not signed by a valid security certificate.
I'm pulling an iframe of an html website into another website but I keep getting the console (chrome) error in the title of this question and in internet explorer it says:
Content was blocked because it was not signed by a valid security certificate.
Your resource probably use a self-signed SSL certificate over HTTPS protocol.
Chromium, so Google Chrome block by default this kind of resource considered unsecure.
You can bypass this this way :
Assuming your frame's URL is https://www.domain.com, open a new tab in chrome and go to https://www.domain.com.
Chrome will ask you to accept the SSL certificate. Accept it.
Then, if you reload your page with your frame, you could see that now it works
The problem as you can guess, is that each visitor of your website has to do this task to access your frame.
You can notice that chrome will block your URL for each navigation session, while chrome can memorise for ever that you trust this domain.
If your frame can be accessed by HTTP rather than HTTPS, I suggest you to use it, so this problem will be solved.
Sometimes Google Chrome throws this error, even if it should not.
I experienced it when Chrome had a new version, and it needed to be restarted.
After restarting the same page worked without any errors.
The error in the console was:
net::ERR_INSECURE_RESPONSE
I still experienced the problem described above on an Asus T100 Windows 10 test device for both (up to date) Edge and Chrome browser.
Solution was in the date/time settings of the device; somehow the date was not set correctly (date in the past). Restoring this by setting the correct date (and restarting the browsers) solved the issue for me. I hope I save someone a headache debugging this problem.
Offering another potential solution to this error.
If you have a frontend application that makes API calls to the backend, make sure you reference the domain name that the certificate has been issued to.
e.g.
https://example.com/api/etc
and not
https://123.4.5.6/api/etc
In my case, I was making API calls to a secure server with a certificate, but using the IP instead of the domain name. This threw a Failed to load resource: net::ERR_INSECURE_RESPONSE.
open up your console and hit the URL inside. it'll take you to the API page and then in the page accept the SSL certificate, go back to your app page and reload.
remember that SSL certificates should have been issued for your Dev environment before.
If you're developing, and you're developing with a Windows machine, simply add localhost as a Trusted Site.
And yes, per DarrylGriffiths' comment, although it may look like you're adding an Internet Explorer setting...
I believe those are Windows rather than IE settings. Although MS tend to assume that they're only IE (hence the alert next to "Enable Protected Mode" that it requries restarted IE)...
Try this code to watch for, and report, a possible net::ERR_INSECURE_RESPONSE
I was having this issue as well, using a self-signed certificate, which I have chosen not to save into the Chrome Settings. After accessing the https domain and accepting the certificate, the ajax call works fine. But once that acceptance has timed-out or before it has first been accepted, the jQuery.ajax() call fails silently: the timeout parameter does not seem help and the error() function never gets called.
As such, my code never receives a success() or error() call and therefore hangs. I believe this is a bug in jquery's handling of this error. My solution is to force the error() call after a specified timeout.
This code does assume a jquery ajax call of the form jQuery.ajax({url: required, success: optional, error: optional, others_ajax_params: optional}).
Note: You will likely want to change the function within the setTimeout to integrate best with your UI: rather than calling alert().
const MS_FOR_HTTPS_FAILURE = 5000;
$.orig_ajax = $.ajax;
$.ajax = function(params)
{
var complete = false;
var success = params.success;
var error = params.error;
params.success = function() {
if(!complete) {
complete = true;
if(success) success.apply(this,arguments);
}
}
params.error = function() {
if(!complete) {
complete = true;
if(error) error.apply(this,arguments);
}
}
setTimeout(function() {
if(!complete) {
complete = true;
alert("Please ensure your self-signed HTTPS certificate has been accepted. "
+ params.url);
if(params.error)
params.error( {},
"Connection failure",
"Timed out while waiting to connect to remote resource. " +
"Possibly could not authenticate HTTPS certificate." );
}
}, MS_FOR_HTTPS_FAILURE);
$.orig_ajax(params);
}
This problem is because of your https that means SSL certification. Try on Localhost.

Displaying KMZ files behind protected networks

I'm trying to display a KMZ file which resides in a folder that is password protected and has a port different from 80. It looks like this:
http://localhost:8080/assets/data/3641
That will return a KMZ file with the valid MIME type, and I can save and open it in Google Earth if I access this link in the browser.
Google Earth's API has the following methods for displaying KMZ/KML:
KmlNetworkLink - you provide the URL of the KMZ/KML and then attach this object to the GE instance
parseKml() - you provide it a KML string, it gives you back a KmlFeature to attach
fetchKml() - you provide it a URL to a KML/KMZ, it attaches it for you
Another handy method is displayKml() from the Google Earth API Utility library, which uses fetchKml()
fetchKml()
My first attempt was to use fetchKml, but this gives no response - it fails silently. I'm surprised this is considered normal behaviour by the plugin (why doesn't it throw an exception, or provide a second callback to handle errors?). This method works fine if I provide it a sample kmz in the form:
http://localhost/somefile.kmz
I believe the issue is the fact that my first URL is password protected - it will redirect to a login screen if no login session is present, and I suspect that the Google Earth plugin doesn't share the same browser session as the browser - so it runs into a login screen and fails because it receives an HTML file instead of a KMZ/KML.
parseKml()
Pressing on undeterred, I made another API method to unzip the KMZ on the server side and return the KML string:
http://localhost:8080/assets/data/unzip/3641
The beauty of this method is that I write my own JavaScript to perform the GET request - it doesn't go through Google Earth, so the login session I have opened is used and the KMZ can be downloaded. The downfall is that KMZs can contain images and music which the KML file can reference. These can't be passed along with the KML string as far as the documentation is concerned.
KmlNetworkLink
My last attempt was to use KmlNetworkLink and KmlLink. This has the same effect as fetchKml - nothing happens.
UPDATE: Also, it will fail when using "https" without a valid certificate.
Yes the issue is that URL is password protected. You can get fetchKml() to give some indication of the error if you use it like so:
google.earth.fetchKml(ge, 'http://localhost:8080/assets/data/3641
', finishFetchKml);
function finishFetchKml(kmlObject) {
// check if the KML was fetched properly
if (kmlObject) {
// add the fetched KML to Earth
currentKmlObject = kmlObject;
} else {
// setTimeout prevents a deadlock in some browsers
setTimeout(function() {
alert('Bad or null KML.');
}, 0);
}
}
Kml is designed to be a free open format - if you wish to use it privately on a secure system then you should look at using the enterprise version of the Google Earth Plugin.

Is there a way to grab a webpage with Actionscript??? I get a SecurityError

I am trying to grab a webpage with actionscript, but keep getting this error (example trying to grab github.com):
[SWF] /get-webpage.swf - 2,708 bytes after decompression
Error: Request for resource at http://github.com by requestor from
http://localhost:4567/get-webpage.swf
is denied due to lack of policy file permissions.
* Security Sandbox Violation *
Connection to http://github.com halted
- not permitted from http://localhost:4567/get-webpage.swf
Is there any way to make that work in Actionscript? How does the crossdomain.xml file play into this? From my understanding, a website puts a crossdomain.xml at their root, specifying that a swf can access their stuff. Is that correct? What do I need to make the above work? The code I'm working with is basically this:
var request:URLRequest = new URLRequest("http://github.com")
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, complete);
loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, error);
loader.load(request);
function complete(event:Event):void {
trace(event.target.data);
}
function error(event:SecurityErrorEvent):void {
trace(event.text);
}
With this in the HTML file:
var flashvars = {};
var params = {allowscriptaccess: "always"};
var attributes = {id: "my_flash", name: "my_flash"};
swfobject.embedSWF("/get-webpage.swf", "flash_content", "50%", "50%", "10.0.0", "playerProductInstall.swf", flashvars, params, attributes, swfHasLoadedSir);
Is it possible to get around that security error?
SHORT ANSWER, NO.
MEDIUM ANSWER, NO.
I see that github has a crossdomain xml policy here.
https://github.com/crossdomain.xml
This is the file that flash automatically loads when it tries to content from another domain.
This xml file is saying, only allow flash on github to suck down data. So github has explicitly said that they dont want you using flash to load any Of their content.
<?xml version="1.0" encoding="UTF-8"?>
<cross-domain-policy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.adobe.com/xml/schemas/PolicyFile.xsd">
<allow-access-from domain="github.com" />
<allow-access-from domain="gist.github.com" />
<site-control permitted-cross-domain-policies="master-only"/>
</cross-domain-policy>
I think the reasoning for this flash behaviour is so that people + companies will trust flash. I think this mechanism could prevent massive DOS attacks (think of a Flash Banner loaded on a news site hitting say, github, it could cause a massive load).
You could email github and get your domain added to their list in the crossdomain file but that could take sometime and lots of politics.
LONG ANSWER, YES.
You could create a HTTP Proxy using PHP or something this to pull in a webpage.
The PHP or code would have to run on the same domain as you loaded your SWF file from. eg youdomain.com/folder/proxy.php . You would have to basically ask this proxy to fetch you a web page in PHP and return the results back to flash. This whole process is a bit of pain especially if you hare acting with a web service where you have to send parameters or HTTP headers. There are open source PHP proxy files online that you can install.
Good Luck! Back to watching Transformers 2 with Megan Fox. Oh yeah.

Resources