PDA

View Full Version : MYSQL Connector Component, V1.0


mmm..pi..3.14..
06-23-2007, 11:29 PM
Long time, never seen...

Been working on this component off and on for over a year now, and I've used it on about 25 sites, so I thought it would be nice to let other people use it.

Basically it creates a link between Flash and MySQL using PHP (works with ASP.NET script too, but that is not ready for public release, so for now that stays with me). All that is needed is a working MySQL database and the mysql module for PHP must be installed. If you can connect to MySQL with PHP already, you should not need to bother checking anything.

Most of the common functions used in MySQL can be used in Flash with this component, below is the complete list:

mysql_connect()
mysql_select_db()
mysql_query()
mysql_fetch_assoc()
mysql_fetch_array()
mysql_fetch_row()
mysql_data_seek()
mysql_num_rows()
mysql_insert_id()

See the php documentation for each of those functions for parameter usage. Some parameters are not available in the flash versions of these functions, such as the "$client_flags" parameter in mysql_connect() The reason for that is either because I could not find a way to integrate that into the component, or I did not feel it was necessary (take your pick :p)

Here is an example of usage in flash (works as long as the MySQL Connector component is on the stage, doesn't need an instance name):


$Connection = mysql_connect("localhost", "username", "password");
trace($Connection); // Outputs: "Resource id #1"

// Both of the following methods work, since by default it uses
// the last open connection. You can give it the resource to select the db
// on, or omit it, in which case it will select the db for the last open connection

mysql_select_db("my_db", $Connection);
mysql_select_db("my_db");

// Once again, you can specify the resource to run the query on or not,
// it defaults to the last open connection

$MyQuery = mysql_query("SELECT * FROM my_table", $Connection);
$MyQuery = mysql_query("SELECT * FROM my_table");
trace($MyQuery); // Outputs: Resource id #2

// I have added the onResult function to the component, because unlike
// PHP, flash executes all script, without waiting for each line of code
// to finish executing (PHP/MySQL users should know what I'm talking about)

$MyQuery.onResult = function(OK){
if(OK){
trace(this);
// OR
trace($MyQuery);
// the above script outputs the query results exactly the same as it
// does when you run queries in the MySQL command prompt

// You can replace "this" with $MyQuery, doesn't matter which though
while($Row = mysql_fetch_assoc(this)){
trace($Row['column_name']);
}
// Could also do the following
// MYSQL_BOTH, MYSQL_ASSOC, and MYSQL_NUM are global variables
// stored in the component
while($Row = mysql_fetch_array(this, MYSQL_BOTH)){
trace($Row['column_1_name']);
trace($Row[0]);
// Both of the above output the same thing, since we
// used MYSQL_BOTH. If you used mysql_fetch_row(), you could
// also specify $Row[0], but not $Row['column_1_name']
}
}else{
// Something wrong happened, flash could not communicate with the db
}
}
// Connections close automatically, so there is no need for mysql_close()


The component will not allow simultaneous queries to run on the same connection, however I have built in a "Pending" class which lets you run multiple queries without screwing up something. The queries run in the order you have them in your script. The first query runs, broadcasts the "onResult" message, then runs the next query in line (if there is one), and so on... The reason for not allowing multiple queries to run simultaneously is because some queries run faster than others. If you need the script that runs after Query 1 gets a result to run before you execute Query 2, then it is good thing only 1 can run at a time. If multiple queries could run at once, Query 2 might get a result before Query 1, therefore causing problems.

You can run simultaneous queries if you would like, but they need to made on different resources. An example would look like this:


$Connection1 = mysql_connect("localhost", "username", "password");
$Connection2 = mysql_connect("localhost", "username", "password", true); // force a new connection, since we used the same credentials (see http://fr3.php.net/manual/en/function.mysql-connect.php, under the new_link parameter)
trace($Connection1); // Outputs: Resource id #1
trace($Connection2); // Outputs: Resource id #2

$Query1 = mysql_query("SELECT * FROM table_1", $Connection1);
$Query2 = mysql_query("SELECT * FROM table_2", $Connection2);

// Both queries run at the same time because they were made on different connections

$Query1.onResult = function(){
trace(this);
}
$Query2.onResult = function(){
trace(this);
}


In that script you might get the results from Query 2 back first, just depends on the query really.

The component itself has 3 parameters, Debugger, HTML Text, and Connector URL

Debugger

If turned on, query syntax errors and messages about not being able to connect to the connector url will output. The debugger works in flash and in web pages. If in flash, it will display the errors in the trace window. If in a web site, it will display the errors in a javascript alert window. Just makes it a bit more easy to debug.

HTML Text

If set to true, special html characters are converted to their html entities (i.e. - & becomes &, Æ becomes Æ, etc...)

If set to false, html entities are turned into their html text character (" becomes ", © becomes ©, etc...)

MySQL Connector URL

Pretty simple, the url to the PHP file.

Below is the script to "color" the mysql related function/variables. Copy to your AsColorSyntax.xml file, inside the <colorsyntax> element.


<keyword text="mysql_connect"/>
<keyword text="mysql_select_db"/>
<keyword text="mysql_query"/>
<keyword text="mysql_fetch_assoc"/>
<keyword text="mysql_fetch_array"/>
<keyword text="mysql_fetch_row"/>
<keyword text="mysql_num_rows"/>
<keyword text="mysql_insert_id"/>
<keyword text="mysql_data_seek"/>
<keyword text="MYSQL_BOTH"/>
<keyword text="MYSQL_NUM"/>
<keyword text="MYSQL_ASSOC"/>


Installation:

Copy the MySQLConnector.swc file to C:\Documents and Settings\<Username>\Local Settings\Application Data\Macromedia\Flash 8\en\Configuration\Components\Data directory. If the "Data" directory does not exist, create it.

MySQL.php needs to go on a server capable of supporting PHP and MySQL. You can change the file name if you would like, just be sure and give the component the correct MySQL Connector URL.

The folder may vary depending on your computer and what version Flash you have. It has been developed in Flash 8, tested in Flash 7 and Flash 8. I do not know about other versions, so don't be surprised if it doesn't work in versions below Flash 7.

Enjoy :)

Flash Gordon
06-24-2007, 01:02 AM
$Connection = mysql_connect("localhost", "username", "password");
trace($Connection); // Outputs: "Resource id #1"


Thanks Eric! :) Looks like a great component

But 1 question: are you advocating putting user names and passwords in Flash?

mmm..pi..3.14..
06-24-2007, 07:20 AM
In order to make it easier to use, you need to do that. If you were really worried about it, you could hardcode the username/password into the php script, just find the part where it calls mysql_connect in the php file, and fill in the info. Then you could enter whatever you wanted into the mysql_connect function in flash (i.e. - fake credentials, just filler parameters), and it would still work.

If anyone knows of a way to secure credentials within flash, without the use of external software, I would love to know about it.

peptobismol
06-25-2007, 06:07 AM
very cool but flash gordon is right.... that's iffy security unless you hardcode like you mentioned...

Maybe you can create a include function that flash can call... The include would be an external php file that has the server info on it...
so it'll look like

include ('serverinfo.php');
$Connection = mysql_connect("localhost", $username, $password);

nothing is given away.

mmm..pi..3.14..
06-25-2007, 07:16 PM
If you hardcode directly into the php file, there is virtually no security risk. PHP files are processed server side, so no one can get the source unless they actually hack into your server, in which case you got alot worse things to worry about.

Did anyone even try it? Honestly, I thought it would get more buzz than this. Saves me a ton of time developing websites. I cut the time it took for me to connect to mysql with flash from about 15 minutes to under 15 seconds, plus it lets me do even more since you can call mysql functions like date_format. think people are too scared about this whole username/password thing, just hardcode and no worries.

mooska
06-27-2007, 10:36 PM
Its not about you know user|pass or not, its about thing you can do with this, and this way you can do anything with sql you want.

Lets say what will happen, when someone will get url of this file, and will send "DELETE *" query ?

sunny747
07-06-2007, 12:12 PM
thanks for an amazing components. Well,i couldn't show the mysql data on the flash even though data is showin up on the output panel.

How to show the data on the flash swf my IE?
thanks so much.

mattkenefick
07-10-2007, 05:47 PM
Well there are many security risks.

For one with User/Pass in Flash - decompilation.
For two with User/Pass in Flash - network analyzer. Anything you send without an SSL to PHP, HTML, Flash, wherever, is going to be clearly readable. That means your queries being sent, all your results (credit card numbers, usernames, passwords, addresses, personal info, anything).

Secondly, I don't really like components. This is just a personal opinion which other people might share. I don't know. I'll include classes, but as for XML Connectors and UI components, I stray away.

Third, AMFPHP is already out. And it's reliable. (Even though it too passes clear text which most people are unaware of)

Cool idea though.

--------
If you could make a really secure one, that'd stir up a ruckus ;)

mmm..pi..3.14..
07-16-2007, 10:12 PM
It works with SSL, but for some reason IE hates it when you use the component in IE. I used it once over the https protocol (PHP script), and it worked just fine with Firefox and other browsers, but IE would not allow flash to connect to the db correctly (IE thing, not flash's fault). The Web Service script however did work just fine in all browsers, over the http or https protocol.

I tried to use AMFPHP, could not get flash to do anything with PHP after several hours of screwing with it. The whole point of my component is to make things user friendly. Couldn't think of any way to make it more user friendly than to keep the same functions as PHP. If someone already knows PHP, they could get the hang of this in a matter of seconds. Just one of my pet peeves really, I hate learning new ways of doing things if you already know how to do it one way.

@sunny747 - once you put the data into an object using mysql_fetch_assoc, mysql_fetch_array, or mysql_fetch_row, you pull the data from that object.


$Data = mysql_fetch_assoc($Result);
myTextBox.text = $Data["Column"];


I have a theory about securing it, but right now flash is doing something... back in a little bit once I test my theory.

mmm..pi..3.14..
07-16-2007, 10:42 PM
How about this for security. Correct me if I am wrong on this, it has been a while since I have used Apache, it's just a theory.

Flash reads all #include files as *.as files basically, so the file does not necessarily have to be a *.as file. I just put some basic actionscript variables into a .htpasswd file and had flash load it (relative path, just "#include '.htpasswd'"). Contained within the htpasswd file was the following:

$dbhost = "here";
$dbuser = "me";
$dbpass = "secret";

Flash was able to read it just fine, trace($dbuser) outputted "me." From what I remember (this is where I would be corrected), servers do not allow files like .htpasswd to be read from remote sources, so navigating directly to the htpasswd file from a browser, or even using loadvars to load it into flash does not work. Of course the file does not need to be a ".htpasswd" file, I tried it with a file called ".Creds" and got a 404 error in the browser, but flash could still find it locally. :)

Is there any reason why that would not work for securing db credentials? I could add another parameter to the component for the htpasswd file, and all you'd have to do is enter that in. You could even put the htpasswd file in the parent directory of the root server directory, and it wouldn't even be accessible by a browser, only from the local machine. Then the path you'd enter into the component parameter would look like "../../../../../.htpasswd" No one would be able to get to it remotely.

jsebrech
07-17-2007, 08:52 AM
All of the flash code runs on the client, so, if flash does the db login, the host/user/password must be sent to the client. Sending it to the client means it can be intercepted (always). So, no matter how convoluted you make things, if the client gets the info, it can be exploited.

Solution: never send the db info to the client, always use a server-side intermediary. The problem is that this means that you can't make direct connections to the db. In this case security and convenience are mutually exclusive.

An alternate solution is to implement security inside the database, by forbidding actions that aren't allowed for a specific user with triggers or something comparable. I have no idea whether mysql can do this however.

mmm..pi..3.14..
07-17-2007, 06:42 PM
Wow... people are paranoid. What put the fear of all things digital into you folks, haha :p

Back in a year with something else maybe. Seems I should give up on this component.

Scuba_Steve
07-18-2007, 04:52 PM
i'm looking for an excuse to use this comp.:) even with the "security" fear, if you hardcode the stuff into the php or use a separate include, the security issue is gone completely.

mattkenefick
07-18-2007, 05:31 PM
i'm looking for an excuse to use this comp.:) even with the "security" fear, if you hardcode the stuff into the php or use a separate include, the security issue is gone completely.

security issues are never "gone completely".

Even executing queries from Flash is a bad idea because then you're sending out your table / row / etc information. Makes things interceptable for SQL injection. Someone decompiles your file. Finds out where your PHP connection is. They just send their own query based on the Query they intercepted from your component that says "DROP ALL TABLES" and goodbye to your database.

Scuba_Steve
07-18-2007, 05:35 PM
ok fair enough but if you combine this comp with a user login where usernames and passwords are stored separately, I think you've mitigated risk sufficiently. sure, someone can always get around security but honestly if someone can get inside my server, i got bigger problems than a dropped database. :)

mattkenefick
07-18-2007, 08:25 PM
ok fair enough but if you combine this comp with a user login where usernames and passwords are stored separately, I think you've mitigated risk sufficiently. sure, someone can always get around security but honestly if someone can get inside my server, i got bigger problems than a dropped database. :)

I'm not saying that. They don't even have to get in your server.

You have a PHP file that takes your post data of $_POST['query'].. does mysql_query($_POST['query'])..

all someone has to do is make a file or just php that says

LVars.query("Destroy all his stuff");
LVars.send("http://yourserver.com/mysql.php");
// haha good-bye

Scuba_Steve
07-18-2007, 09:07 PM
matt, then what's your solution for connecting Flash to mySQL-stored data via PHP?

i also never send a query directly from flash to php. i send values over that the php script itself uses to BUILD the query. flash is never barking orders at the database.

I will agree with you, though, that if i said:

$query = $_post['query'];
...
mysql_query($query);


then yeah, i deserve to have all my crap destroyed. :)

mooska
07-19-2007, 09:27 AM
First of all you dont need php to directly query database.

http://asql.mooska.pl
http://maclema.com/assql

If you want to do something like that, you need to set correctly users privillages ont the mysql server, ie for SELECT query type only. Then its quite good secured.

Scuba_Steve
07-19-2007, 01:53 PM
as i understand both of those, they require the db to be publicly accessible and permissions set on the server to allow "SELECT" only queries. i have some publicly accessible TABLES, but not the db itself. thus my use of php to connect as securely as i know how.

baross
10-16-2007, 12:08 AM
mmm..pi..3.14.. I too am surprised at this reaction I was just searching for things about security then I came across this post entitled sql in flash. I thought whoa thats ****en awesome , why havn't I heard about that before that should be big then I came in here and i was shocked it got slammed. I think its a really good idea and I am going to use it for my project im planning.
So to overcome the security issue you can keep the database info in a php and also in that php make shure that it was accessed from within your domain
http://www.actionscript.org/forums/showthread.php3?t=143173&highlight=security+php.
I think this is the wrong crowd, you should try some people who are just starting out with flash and databases. :)

jsebrech
10-16-2007, 08:55 AM
baross, the level of the flash programmer has nothing to do with the likelihood of that programmer's site getting hacked. An insecure concept is an insecure concept, no matter who implements it. In this case, it would be trivial for an attacker to hack around any "safeguards" you implement (like your suggestion of checking the request came from within the domain).

I also love the idea of being able to run queries directly from flash, but the reality is that it is just not possible to do it securely without building a custom query parser server-side that validates all queries to ensure that they are indeed permitted. There's no alternative (security-wise) for validating absolutely everything server-side.

baross
10-17-2007, 07:55 AM
I see,
I thought that keeping the database login info in a php that gets sent to the asking swf only when it is verified to be in the same domain to be secure enough. how can the user ever get the login info easily ? how can the database be altered in anyway other than what the swf does easily ?

what does this mean ?
"evdog's idea sounds pretty good. it is possible to 'spoof' both _root._url AND one's IP address or domain, but it definitely makes it harder for the hacker if you are checking them against each other."
checking them against each other ?

jsebrech
10-17-2007, 10:51 AM
The attacker doesn't need to know the login info, if he can send a fraudulent query from the client to the server. He doesn't even need to hack the swf in any way for this. He can just intercept the network communications and replace the query the swf sends with one of his own. And yes, there are even mechanisms to do this if you use https.

baross
10-17-2007, 12:34 PM
ok thanks for the info.
how can I do secure flash to databse comincation in anyway ? what do most people do ? flash-php-database ? how can I do this securely ?
I mean im not like a bank or anything I just want to be able to safely say that I probably wont/cant get hacked.
thanks

jsebrech
10-17-2007, 02:30 PM
Well, the basic principle (and this extends to all web apps, not just to flash) is to never trust the client. This means that you use a server-side layer (for example, a php script) that interprets everything the client tries to do and only allows those actions which are explicitly allowed. This also means that when a user submits changes, the server-side script must perform all validation checks on this submitted data. The client's validation checks should only be used as a convenience to the user (because the user doesn't need to wait for a server request before knowing whether his data is valid).