1

I'm making an in-browser game of the type "guess what place/monument/etc. is in this satellite/aerial view", using Google Maps JS API v3. I can't just take a screenshot, as this seems to be specifically forbidden by Permission Guidelines for Google Maps.

However, I need to protect against cheaters - you have to pass a google.maps.LatLng and a zoom level to the map constructor, which means a cheating user only needs to view source to get to this data:

<script type="text/javascript"
  src="http://maps.google.com/maps/api/js?sensor=false"></script> 
<script type="text/javascript"> 
  function initialize() {
    var myOptions = {
      center: new google.maps.LatLng(55, 145), /* this */
      zoom: 10, /* and possibly this */
      mapTypeId: google.maps.MapTypeId.SATELLITE,
    }
    var map = new google.maps.Map(document.getElementById("map_canvas"),
                                    myOptions);
  }
</script> 

I am already unsetting every value I possibly can without breaking the map (such as center and the manipulation functions like setZoom()), and initializing the map in an anonymous function (so the object is not visible in global namespace).

Now, this is of course in-browser, client-side, untrusted JavaScript; I've read much of the tag and I'm not trying to make the script bullet-proof (it's just a game, after all). I only need to make the obfuscation reasonably hard against the 1337 Java5kryp7 haxz0rz - "kid sister encryption", as Bruce Schneier puts it. Anything harder than base64 encoding would deter most cheaters by eliminating the lowest-hanging fruit - if the cheater is smart and determined enough to use a JS debugger, he can bypass anything I can do (as I need to pass the value to Google Maps API in plaintext), but that's unlikely to happen on a mass scale (there will also be other, not-code-related ways to prevent cheating).

I've tried various minimizers and obfuscators, but those will mostly deal with code (which in this case is not the "secret"), the values of variables are still shown verbatim.

At @Pointy's suggestion, I checked the HTTP requests closely, and one of them does send the lat/lon in the URL; although that's disappointing, this request happens between many other requests, so it won't be noticed right away. Fortunately, the goal is only to make it harder to find the lat/lon, not bulletproof.


TL;DR: I need to obfuscate three values in JavaScript. I'm not looking for bullet-proof armor, just a sneeze-guard. What should I use?

Piskvor left the building
  • 91,498
  • 46
  • 177
  • 222
  • 1
    Don't the plaintext values need to go out in the URLs? All somebody would have to do is install TamperData and watch all the HTTP traffic going by ... – Pointy Feb 10 '11 at 15:21
  • @Pointy: 1) not really, although the map tiles (which are requested) have a 1:1 correlation with physical location, and some of the returned JSON data are also closely correlated with the location, but moreover 2) that's waay beyond the knowledge of 90% of users, which is my point. As I said, I don't need a bullet-proof solution, just something to stop a 10-year-old self-professed "l33t haxx0r". – Piskvor left the building Feb 10 '11 at 15:25
  • Well it's your game and your time :-) My point was really that using TamperData (or something like it) is much easier even than using Firebug or something, because it shows all the request and response headers as well as POST bodies. – Pointy Feb 10 '11 at 15:30
  • @Pointy: Actually, you can do that in Firebug, too (Net Panel). Alas, it's not really *my* game, and there's a requirement against plaintext location =/ Maybe I'll go with base64 after all, even though it's worse than plaintext, and a rather distinctive string pattern. – Piskvor left the building Feb 10 '11 at 15:41
  • @Pointy: Aaand you are right - the component responsible for the copyright texts *does* show the location in a GET URL, and in the result it fetches. Oh well... – Piskvor left the building Feb 10 '11 at 15:58
  • Is there any way to *avoid* sending the lat/long to the user at all? I don't know how much interaction you need in the map, but if you could snapshot the map, and just pass the user the map image, they would never need to learn the original lat/long. – zzzzBov Feb 10 '11 at 16:30
  • @zzzzBov: Hmmm, that's a good idea. I don't know whether the ToS for Google Maps allows that - will check. – Piskvor left the building Feb 10 '11 at 16:31
  • @Piskvor, I got the idea from an HTML5 word-guessing game that I found a couple weeks ago. I checked firebug to see if they were sending the word over (making it possible to cheat). They were sending the clue information over with a unique id, and checking the validity on the server. – zzzzBov Feb 11 '11 at 16:12
  • @zzzzBov: Technically it would work, but it seems that it's specifically disallowed: http://www.google.com/permissions/geoguidelines.html – Piskvor left the building Feb 11 '11 at 16:18
  • My first thought was to proxy the Static Map's API via your server, with a less informative URL, but that's [not allowed by Google's ToS either](https://developers.google.com/maps/faq#tos_staticmaps_reuse).. – dbr Feb 11 '13 at 13:25

2 Answers2

1

It will be best to obfuscate your entire code base, instead of just minification. That way, it would be extremely difficult for the user to know which variable to look for the lat/long values.

The Dojo Toolkit can be used with the Closure Compiler in Advanced mode for complete obfuscation. If you use a JavaScript library but also need to obfuscate your whole code to protect your IP, you should consider Dojo.

http://dojo-toolkit.33424.n3.nabble.com/file/n2636749/Using_the_Dojo_Toolkit_with_the_Closure_Compiler.pdf?by-user=t

Stephen Chung
  • 14,497
  • 1
  • 35
  • 48
0

dont waste your time with the obsfucation. compress the code (yuic, closure) and done with it. as you said, the code runs @client side, no point in obsfucating anything.

eg, something like this:

for (var secret = 0; secret < 10; secret++) {
   alert(secret);
}

gets 'closured' into this:

for(var a=0;a<10;a++)alert(a);

you can play around with closure online

if you want to explicitly 'hide' data segments: compress / 'crypt' them in some form, JavaScript implementation of Gzip might help with that.

Community
  • 1
  • 1
akira
  • 6,050
  • 29
  • 37
  • Thank you for the suggestion, I've edited in my results with obfuscators. However futile in general, there *is* a point in obfuscation, and that lies in __limited knowledge__: many people can do Ctrl+U and vgrep the source for something that looks like a lat/lon pair, much fewer will notice a base64 string, and even fewer will be capable of setting up a JS debugger(yes,one is built into Chrome,but who knows this?).A typical bike lock is equally "useless", as a knowledgeable thief opens it in 10 seconds;its value is in deterrence (as not everyone is a bike thief *and* knowledgeable). – Piskvor left the building Feb 10 '11 at 15:32
  • Gzip looks promising, will look into that. – Piskvor left the building Feb 11 '11 at 17:12