I'm working on a major Flash project that is going to be the core content of a site.
As most of you well know, almost any site can be entirely copied by copying the cached files and the hierarchy (files and folders structure), and it would run without problems on an Apache server with PHP enabled, if used.
What I would like to know is: How to bind SWF files to run on a specific host?
The SWFs will be encrypted, so outsiders won't have access to the methods used to stop the SWF from running on a different host, question is: what method to use?
I think the solution could be hardcoding the host IP inside the SWF, so if the SWF is looking for 123.123.123.123, only a host with that IP would allow the SWF to run further.
The issue is that AS3 alone can't discover the host IP or could it if it's trying to load a resource file? Anyway, that's why I need your help.
EDIT: Ok, seems someone asked for something similar earlier: Can you secure your swf so it checks if it is running on a recognized environment?
I'll try that and see how it works, but the question is still open in case anyone has different suggestions.
I use this method to determine if I am on dev or production in my config files.
var lc:LocalConnection = new LocalConnection();
switch ( lc.domain ){
case "myDomain.com":
case "":// local file reference for dev
case "localhost":// local file reference for dev
case "dev.mydomain.com":// local file reference for dev
break;
default:
// unknown domain do crash the app here
}
One method you could try is a php script that the swf sends a request to and must receive a correct reply from before it continues to operate. Since people can't get at your server-side php, they can't get the needed code to simulate that reply.
The SWFs will be encrypted, so outsiders won't have access to the methods used to stop the SWF from running on a different host
Since the file will run on a client computer (and thus they key would have to be stored in an accessible way), this isn't really that much of a protection.
The best way would probably be to have part of the SWF-logic on the server, and not give access to that part from third party hosts (by using the crossdomain file).
Look into the idea of wrapping main inside a type of preloader, and putting main into a secure dir on the server. I cant remember how this gets around the cache problem, but it had to do with how the wrapper loads main.
Something like this:
// preloader.as (embedded in fla)
var imageLoader:Loader;
function randomNumber(low:Number=NaN, high:Number=NaN):Number
{
var low:Number = low;
var high:Number = high;
if(isNaN(low))
{
throw new Error("low must be defined");
}
if(isNaN(high))
{
throw new Error("high must be defined");
}
return Math.round(Math.random() * (high - low)) + low;
}
function loadImage(url:String):void {
imageArea.visible=false;
preloader.visible = true;
// Set properties on my Loader object
imageLoader = new Loader();
imageLoader.load(new URLRequest(url));
imageLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, imageLoading);
imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, imageLoaded);
imageArea.addChild(imageLoader);
}
// DOIT!
loadImage("main.sw?"+randomNumber(1000,10000)); //NOT A TYPO!
//loadImage("main.swf"+randomNumber(1000,10000);
function imageLoaded(e:Event):void {
// Hide Preloader
preloader.visible = false;
}
function imageLoading(e:ProgressEvent):void {
// Get current download progress
var loaded:Number = e.bytesLoaded / e.bytesTotal;
// Send progress info to "preloader" movie clip
preloader.SetProgress(loaded);
}
/// this is main.sw //NOT A TYPO
<?php
// Tried this - abandoned
// session_start();
//
// if(isset($_SESSION["flash"])) {
// $referrer = $_SERVER["HTTP_REFERER"];
// $referrer = parse_url($referrer);
// if($referrer["host"] != $_SESSION["flash"]) {
// echo "Permission denied.";
// exit();
// }
// } else {
// echo "Permission denied.";
// exit();
// }
//
// unset($_SESSION["flash"]);
header("Content-type: application/x-shockwave-flash");
readfile("/secure/main.swf");
?>
// main.as
public function onCreationComplete(event:Event):void{
Security.allowDomain( "*" );
Security.loadPolicyFile( "crossdomain.xml" );
}
// crossdomain.xml
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="*" />
</cross-domain-policy>
That should get you started. The idea here was to prevent anyone from getting main on their machine- I am not sure if it worked.
You may have a server-side page generate a key using a date-based algorithm which is passed via flash var to your swf. This way a "copied" key won't work because by that time, the valid date will have passed. From what I understand, this would essentially be like using an RSA token.
Aside from this, any security you have will also need code to be inside your SWF to validate your token. The problem here is that SWFs are known to decompile quite easily. Meaning that your code isn't safe :( You could obfuscate your AS3 in hopes to confuse any "hackers".
All in all, I've never attempted anything like this, so let us know how it goes!
Related
I am using Birt 4.5 and PHP/MYSQL.
I am able to run birt reports with php. I have enabled tomcat and copied 'birt-runtime-4_5_0/WebViewerExample' to tomcat/webapps and renamed it to birt.
So I can run birt viewer with php;
<?php
$fname = "report/test.rptdesign&__showtitle=false";
$dest = "http://localhost:8081/birt/frameset?__report=";
$dest .= $fname;
header("Location: $dest" );
?>
Above code is working fine. But report connectstring already saved in test.rptdesign file.
I want to remove DB login credentials from test.rptdesign file and assign it while report open with PHP.
I have tried with report parameters. But all the parameters will display on browser address-bar.
Is there any secure way to do this? This is very important when we need to change the database location. It is very hard to change the data source of each and every .rptdesign file.
Thank You,
Supun
I don't believe using report parameters to handle a database connection is the right way. In addition to the address-bar problem you mentionned, it will cause unexpected issues: for example you won't be able to use this database to feed the dataset of another report parameter.
With Tomcat the best approach is to externalize the database connection in a connection pool: easy, robust, and reports might run significantly faster.
Alternatively the datasource can be externalized in a BIRT library (.rptlibrary) and shared across all report-designs: thus only the library needs to be updated when the database location is changing.
I agree with Dominique that sending the database parameters via the query is most likely an inappropriate solution - and you've not given any explanation of whether this is a requirement of the system.
But it is quite trivial to proxy the request via PHP and decorate the URL with the required parameters, something like...
<?php
$_GET['__showtitle']=$_GET['__showtitle'] ? $_GET['__showtitle'] : 'false';
$_GET['__report']=$fname; // NB this should be NULL in your code!
$_GET['dbuser']='a_db_user';
$_GET['passwd']='s3cr3t';
$qry=http_build_query($_GET);
$url="http://localhost:8081/birt/frameset?" . $qry;
// if its simply returning HTML, then just....
$fin=fopen($url, 'r');
while ($l=fgets($fin)) {
print $l;
}
exit;
If the returned content contains relative links the you'll need to rewrite the output stream. If the content type is unusual or you want to project other headers (e.g. for caching) to the browser, then you'll need to use Curl, capture the headers and relay them.
I got an application which uses flash for it's interfaces, and I want to extract information from this application, and parse/use it in my own application (which processes the data, stores the essentials in a mysqldb and so on).
The .swf files are written in AS2 and can be modded quite easily.
So my goal is to send information (really just information. Being able to send numbers (of a at least decent size) would enable me to implement my own protocol of encoding and partitioning) by any means, I am certainly not picky about the means.
Here is my current approach (not my own idea, credits to koreanrandom.org. I merely use their source to learn):
use DokanLib to mount a virtual filesystem (and implement the getFileInformation-handler)
use LoadVars inside the AS2-Environment with parameters like "../.logger/#encoded_information"
since getFileInformation gets the accessed filename as a parameter, I can decode it, put several ones back together (if they had to be splitted, windows does not seem to like filenames with several hundred characters length) and use the decoded data
However, my application causes bluescreens quite often (dont ask why. i got no clue, the bluescreen messages are always different) and the devs at koreanrandom.org dont like being asked too many questions, so i came to ask here for other means to pass information from a sandboxed flash-environment to a prepared listener.
I started thinking about weird stuff (ok, abusing a virtual filesystem & filenames as a means of transport for information might be weird too - but it is still a great idea imo) like provoking certain windows-functions to be called and work with global hooks, but i didnt grasp a serious plan yet.
The "usual" methods like accessing webservers via methods like this dont appear to work:
var target_mc = createEmptyMovieClip("target_mc", this.getNextHighestDepth());
loadVariables("http://127.0.0.1/Tools/indata.php", "target_mc", "GET");
(indata.php would have created a file, if it was accessed, but it didnt.)
XMLSocket doesnt work either, i tried the following code sample (using netcat -l on port 12345):
Logger.add("begin");
var theSocket:XMLSocket = new XMLSocket();
theSocket.onConnect = function(myStatus) {
if (myStatus) {
Logger.add("XMLSocket sucessfully connected")
} else {
Logger.add("XMLSocket NO CONNECTION");
}
};
theSocket.connect("127.0.0.1", 12345);
var myXML:XML = new XML();
var mySend = myXML.createElement("thenode");
mySend.attributes.myData = "someData";
myXML.appendChild(mySend);
theSocket.send(myXML);
Logger.add("socket sent");
doesnt work at all either, the output of the logger was just begin and socket sent
Annotation: the logger was created by the guys from koreanrandom.org and relies on their dokan implementation, which never caused a bluescreen for me. cant spot my mistake in my implementation though, so i started to look for other means of solving my problem.
EDIT: what the hell is wrong with your "quality messages system"? appearently it didnt like me using the tags "escaping" and/or "information".
hmm, hard to say, try sendAndLoad instead of loadVariables
example:
var result_lv:LoadVars = new LoadVars();
var send_lv:LoadVars = new LoadVars();
send_lv.variable1=value1;
send_lv.variable2=value2;
f=this;//zachytka
result_lv.onLoad = function(success:Boolean) {
if (success) {
trace("ok");
} else {
trace("error");
}
};
send_lv.sendAndLoad("http://127.0.0.1/Tools/indata.php", result_lv, "GET"); //you may also use POST
this should work. the reason it's not working may also be flash security settings. try either moving the stuff to a real server or open up the flash settings manager (there's an alternative online version too) and add the 127.0.0.1 to trusted domains and/or testing file location to the trusted locations (i use C:*)
First: please forgive me - Im a bit of a novice as some of this...
I have a working test site which is running the php facebook SDK to perform some simple graphAPI requests successfully. Namely read a group's feed, which the user is a member of, and process this and display it back on a webpage.
This all works fine, the problem I have encountered is when trying to perform the same request via a php curl POST to another webpage (on the same domain). It seems that the SDK does not carry the expected session to another page when a post request is formed (see "AUTH ERROR2" in code)...this works fine when the following file is included via a "require_once" but not when a curl is made.
I would much rather do a "curl" as Im finding when a "require_once" is done from a page in a different directory level, Im getting php errors of the page not being found - which is expected.
I may just be tackling this problem all wrong...there may be a simpler way to make sure when files are includes, their correct directly level remains intact, or there may be a way to send over the currently authorised facebook sdk session via a curl post. All of which I have tried to no avail, and I would really appreciate any help or advise on this.
Thank you for your time.
//readGroupPosts.inc.php
function readGroupPosts($postVars)
{
//$access_token = $postVars[0];
// ^-- I'm presuming I need this? I have been experimenting appending it to
// the graphAPI request to no success...
$groupID = $postVars[1];
$limit = $postVars[2];
require_once("authFb.inc.php"); //link to the facebookSDK & other stuff
if ($user) {
try {
$groupFeed = $facebook->api("/$groupID/feed?limit=$limit"); //limit=0 returns all;
$groupFeed = $groupFeed['data']; //removes first tier of array for simpler access
$postArray;
for($i=0; $i<count($groupFeed); $i++)
{
$postArray[$i] = array($groupFeed[$i]['from']['name'], $groupFeed[$i]['message'], $groupFeed[$i]['updated_time'], count($groupFeed[$i]['likes']['data']));
}
return $postArray;
} catch (FacebookApiException $e) {
error_log($e);
$user = null;
return "AUTH ERROR1"; //for testing..
}
}
else
{
return "AUTH ERROR2"; //no user is authenticated i.e. $user == null..
}
}
I would much rather do a "curl" as Im finding when a "require_once" is done from a page in a different directory level, Im getting php errors of the page not being found - which is expected.
I may just be tackling this problem all wrong...
Definitively.
Using cURL as a “workaround” just because you’re not able to find your way around your server’s file system is an outrageous idea. Don’t do it. Stop even thinking about it. Now.
there may be a simpler way to make sure when files are includes, their correct directly level remains intact
Yes – for example, to use absolute paths instead of relative ones. Prefixing the path with the value of $_SERVER['DOCUMENT_ROOT'] for example – that way, once you’ve given the path correctly in respect to this “base path”, it does not matter where you’re requiring the file from, because an absolute path is the same no matter from where you look at it.
(And since this is not a Facebook-related problem at all, but just concerns basics of PHP and server-side programming, I’ll edit the tags.)
This is how I call the editor:
new nicEditor({
buttonList : ['bold','italic','underline','upload'],
iconsPath:'img/nicedit.png',
uploadURI : 'http://server.com/integracion/files/nicUpload.php'
}).panelInstance(textareaId);
And the .php file exists ( and I the one in the Docs, and I updated the target paths )
/* I want them here http://server.com/integracion/files/uploads/ so... */
define('NICUPLOAD_PATH', './uploads'); // Set the path (relative or absolute) to
// the directory to save image files
define('NICUPLOAD_URI', '/uploads'); // Set the URL (relative or absolute) to
// the directory defined above
But I on response when upload completes (and of corse an alert from nicedit..)
<script>
try {
top.nicUploadButton.statusCb({"error":"Invalid Upload ID"});
} catch(e) { alert(e.message); }
</script>
what am I missing?
-EDIT
I think the problem might be in the php file:
$id = $_POST['APC_UPLOAD_PROGRESS']; /* APC is installed and enabled */
if(empty($id)) {
$id = $_GET['id'];
}
FINAL EDIT:
I have managed to make this work!
Here is an working example:
http://simplestudio.rs/yard/nicedit/
Uploaded images are going to be stored here:
http://simplestudio.rs/yard/nicedit/images/
And here is the whole code, just unpack it and put on your server, mainly I needed to adjust nicEdit.js because it had some issues.
http://simplestudio.rs/yard/nicedit/nicedit.rar
Just make your code with that js file and by looking at my example, it will work :)
Also you need to have php APC installed so that this script can work:
http://php.net/manual/en/apc.installation.php
If you by any mean have some problems I am here to solve it.
I will not delete this example on my server so that everybody who have this issue can freely download it...
The code responsible for image upload is the method uploadFile, it is looking for uploadURI option parameter.
You will need to modify onUploaded event handler to parse your custom response instead of the imgur's one (sample). By default it expects at least {"upload": { "links": {"original": "http://..."}, "image": {"width": "123" } }}.
I'm sorry but I can't help with the FormData() handling server side with PHP.
For more information you can try out the demo page on the nicEdit web site using Firebug or WebInspector to snoop the network requests, and, of course, the source code.
I have a music player that links to a song using the following syntax:
<li>title</li>
Is there any way that I could have that executed server side and then be displayed like (see below) for the user?
While searching, I ran across this...I like the idea behind having an external file that has the data...like:
<?php
// get-file.php
// call with: http://yoururl.com/path/get-file.php?id=1
$id = (isset($_GET["id"])) ? strval($_GET["id"]) : "1";
// lookup
$url[1] = 'link.mp3';
$url[2] = 'link2.mp3';
header("Location: $url[$id]");
exit;
?>
then using: http://yoururl.com/path/get-file.php?id=1 as the link...the only problem is that when you type http://yoururl.com/path/get-file.php?id=1 the user goes straight to the file...is there any way to disable that ability...maybe some code on get-file.php itself?
Ok, so I did a combination of things that I am satisfied with...although not completely secure, it definitely helped me obscure it quite a bit.
First of all, I am using the AudioJS player to play music - which can be found: http://kolber.github.com/audiojs/
Basically what I did was:
Instead of using "data-src" as the path to my songs I called it "key", that way people wouldn't necessarily think it was a path.
Instead of using "my-song-title" as the name of the songs, I changed it to a number like 7364920, that way people couldn't look for that in the source and find the url that way.
I added + "mp3" to the javascript code after all of the "key" variables, that way I would not have to declare it in obfusticated link.
I used a relative path like "./8273019283/" instead of "your-domain.com/8273019283/", that way it would be harder to tell that I was displaying a url.
Added an iTunes link to the href, that way people might get confused as to how I was pulling the file.
So, now my inline javascript looks like:
<script type="text/javascript">
$(function() {
// Play entire album
var a = audiojs.createAll({
trackEnded: function() {
var next = $("ul li.playing").next();
if (!next.length) next = $("ul li").first();
next.addClass("playing").siblings().removeClass("playing");
audio.load($("a", next).attr("key") + "mp3");
audio.play();
}
});
// Load the first song
var audio = a[0];
first = $("ul a").attr("key") + "mp3";
$("ul li").first().addClass("playing");
audio.load(first);
// Load when clicked
$("ul li").click(function(e) {
e.preventDefault();
$(this).addClass("playing").siblings().removeClass("playing");
audio.load($('a', this).attr('key') + "mp3");
audio.play();
});
});
</script>
My link looks like:
Falling
When you load it up in the browser and you view the source you'll see:
Falling
Then when you use Web Inspector or Firebug you'll see:
Falling - *which doesn't completely give the url away
Basically what I did was make the link look like it's an api-key of some-kind. The cool thing is that you can't just copy the link straight from view source or straight from Web Inspector/Firebug. It's not fool-proof, and can definitely be broken, but the user would have to know what they're doing. It keeps most people away, yet still allows the player to get the url it needs to play the song :)
*also, I got the php obfusticate script from somewhere on Stack Exchange, just not sure where.
Instead of doing a header redirect, add proper headers and include the audio file in your PHP code. Then, in your .htaccess file, you can disallow access to the directory where your audio files live.
If you are using amazon s3 service you can use signed url for your files. It will be more safe as you have to be signed user and also url can be expired. Read this.
No. This is not possible since it is the browser that interprets the HTML to make the page work properly. So if the client (browser) does not know where the mp3 is coming from then it will not be there to use.
On the other hand if you want to have the music switch songs by clicking a link then i suggest you look into some tools like http://jplayer.org/
EDIT: The only way to probably prevent direct access to the file itself would be to read the file in instead of linking to it from the script. For instance on my image hosting site http://www.tinyuploads.com/images/CVN5Qm.jpg and if you were to look at the actual file path on my server, the file CVN5Qm.jpg is out of view from the public_html folder. There is no way to directly access the file. I use databases to take the image id, look up where it is stored, and then readfile() it into the script and display the proper headers to output the image.
Hope this helps
I use http_referer and I can controll the procedence of the link
<?php
// key.php
// call with: http://yoururl.com/path/key.php?id=1
$page_refer=$_SERVER['HTTP_REFERER'];
if ($page_refer=="http://www.yourdomine.com/path/page.html")
{
$id = (isset($_GET["id"])) ? strval($_GET["id"]) : "1";
// lookup
$url[1] = 'link1.mp3';
$url[2] = 'link2.mp3';
header("Location: $url[$id]");
exit;
}
else
{
exit;
}
?>