2

I'm working with a very simple mock-up application to query a DB and display the results on a map. The application sends a GET httprequest to a server which returns a serialized array of value. The basic structure of the httprequest is:

httpRequest.open("GET","handle-query.php?query=" + queryJs)

and, on the other side:

$queryPhp = $_GET["query"];

When the query looks like this...

["SELECT%SUM(commit)%FROM%financialdata%WHERE%region='Centre'", "SELECT%SUM(commit)%FROM%financialdata%WHERE%region='Kara'", "SELECT%SUM(commit)%FROM%financialdata%WHERE%region='Maritime'", "SELECT%SUM(commit)%FROM%financialdata%WHERE%region='Plateaux'", "SELECT%SUM(commit)%FROM%financialdata%WHERE%region='Savanes'"]

...then it is passed to the server properly, and generates a response. However, when the query looks like this...

["SELECT%SUM(commit)%FROM%financialdata%WHERE%prefect='Sotouboua'", "SELECT%SUM(commit)%FROM%financialdata%WHERE%prefect='Tchamba'", "SELECT%SUM(commit)%FROM%financialdata%WHERE%prefect='Tchaoudjo'", "SELECT%SUM(commit)%FROM%financialdata%WHERE%prefect='Assoli'", "SELECT%SUM(commit)%FROM%financialdata%WHERE%prefect='Bassar'", "SELECT%SUM(commit)%FROM%financialdata%WHERE%prefect='Bimah'", "SELECT%SUM(commit)%FROM%financialdata%WHERE%prefect='Doufelgou'", "SELECT%SUM(commit)%FROM%financialdata%WHERE%prefect='Keran'", "SELECT%SUM(commit)%FROM%financialdata%WHERE%prefect='Kozah'", "SELECT%SUM(commit)%FROM%financialdata%WHERE%prefect='Golfe'", "SELECT%SUM(commit)%FROM%financialdata%WHERE%prefect='Lacs'", "SELECT%SUM(commit)%FROM%financialdata%WHERE%prefect='Vo'", "SELECT%SUM(commit)%FROM%financialdata%WHERE%prefect='Yoto'", "SELECT%SUM(commit)%FROM%financialdata%WHERE%prefect='Zio'", "SELECT%SUM(commit)%FROM%financialdata%WHERE%prefect='Amou'", "SELECT%SUM(commit)%FROM%financialdata%WHERE%prefect='Haho'", "SELECT%SUM(commit)%FROM%financialdata%WHERE%prefect='Kloto'", "SELECT%SUM(commit)%FROM%financialdata%WHERE%prefect='Ogou'", "SELECT%SUM(commit)%FROM%financialdata%WHERE%prefect='Wawa'", "SELECT%SUM(commit)%FROM%financialdata%WHERE%prefect='Oti'", "SELECT%SUM(commit)%FROM%financialdata%WHERE%prefect='Tone'"]

...then the server receives an empty string. Both of the strings are generated by the same function, and both work perfectly on my virtual server (WAMP). If anyone has any ideas it would be greatly appreciated.

(P.S. After reading I realize that I should be using a framework with better sanitization, etc., but this is just a demo that will need to live online for maybe 2 hours, and it would be better to fix this small thing than start over. It works perfectly on my localhost.)

Owen
  • 1,652
  • 2
  • 20
  • 24
  • 23
    YOU ARE SENDING SQL QUERIES VIA A GET REQUEST? ARE YOU NUTS? [SQL Injection](http://en.wikipedia.org/wiki/SQL_injection) – epascarello Dec 11 '12 at 21:32
  • 6
    You need `encodeURIComponent()` – Pointy Dec 11 '12 at 21:34
  • 1
    If this is a demo that you are showing to anyone beware of termination when they find out you're exposing the db in json calls. (let alone actually passing commands in json....) – Petrogad Dec 11 '12 at 21:36
  • 4
    Come on @Pointy: OP has a gun, wants to shoot himself, doesn't know where the trigger is ... and you give her the answer? –  Dec 11 '12 at 21:37
  • 3
    Just to add to @epascarello: using POST wouldn't be any better. **Just don't send SQL from the client to the server**. And `encodeURIComponent` before sending anything else. – bfavaretto Dec 11 '12 at 21:38
  • 2
    _"a demo that will need to live online for maybe 2 hours"_ It takes one get request to delete all the data in your database! _"It works perfectly on my localhost"_ Opening a window with a hammer also works. – epascarello Dec 11 '12 at 21:39
  • 1
    this should be only voted up so anybody trying to achieve same thing would immeadetly be informed of the risks! And correct answer should be 'BAD PRACTICE' – Tom Dec 11 '12 at 21:40
  • 3
    @Tibo that the approach is comically terrible seems pretty obvious, and `encodeURIComponent()` is important even after the design is changed to something less insane. – Pointy Dec 11 '12 at 21:42
  • 3
    @tibo: at some point, one must thin the herds to prevent the genes which produce this sort of code from propagating. I'd provide a forehead-attachable target along with showing where the trigger is. – Marc B Dec 11 '12 at 21:46
  • 3
    @Pointy, of course. Besides, he might as well be hitting the GET variable size limit, but I'm not letting him know. No way. –  Dec 11 '12 at 21:48
  • 2
    Everyone, thanks for your comments. There is not important data in the db - again, just a mockup. I appreciate mentioning the risks, fyi it's not a demo of programming skills - just a glorified wireframe. – Owen Dec 11 '12 at 22:04

1 Answers1

2

To actually answer your question, you're sending a get parameter as query (handle-query.php?query=) and then pulling it off as queryJS (queryJs).

$_GET['query'] // instead of $_GET['queryJs']

should do it.

(And as everyone has pointed out, don't send SQL in the clear or otherwise over the wire, unless you plan on not actually executing the SQL, and you just like to advertise your db structure, maybe it is that pretty.)

xbakesx
  • 13,202
  • 6
  • 48
  • 76
  • 1
    We were all so perplexed with the injection vulnerability that nobody noticed else that... The value still needs to be properly URL-encoded, though. – bfavaretto Dec 11 '12 at 21:44
  • Thanks for your answer. Actually a typo. Edited above. The code works on the first string, just not on others. – Owen Dec 11 '12 at 22:02
  • Couple of quick things to note: first you really should be url encoding these, especially because you have % in the string, which may get interpreted crazy by the server (I am kind of surprised your local works, so this probably isn't the problem). Second, url encoding just that data gets you a length of 1873 characters that runs really close to the url limit http://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url so try hacking off a few (half) array params and seeing if that helps. – xbakesx Dec 11 '12 at 23:02
  • The only other thing I am seeing right now is that you are keying off a different column in the second, so maybe there's something in your remote database (vs local test environment) that is different and dumping out early. (This assumes that you are in fact getting something on the server for both, and dying before you get to the part where you are checking for something... not exactly high percentage guesses here, sorry) – xbakesx Dec 11 '12 at 23:06
  • Thanks for your suggestion. It is keying off a different column, but I'm not sure why that would be different in the remote vs. local. I've tried shorter lengths and URL-encoding. Aggressive tones of some of the above comments aside, I think it's obvious that I'm too far up a bad solution to try to salvage, so will accept this answer on that basis and go back to the start with a proper framework. Thanks everyone for your advice! – Owen Dec 12 '12 at 19:21
  • It would be a pity to lose a bunch of data because you were passing sql in the request. Good luck! – xbakesx Dec 12 '12 at 20:46