Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Show HN: Game where you write Python robots to fight other players (robotgame.org)
142 points by _g2lm on Nov 1, 2013 | hide | past | favorite | 98 comments


I was looking through the code and saw someone submitted this but didn't run it:

    def x():
        g = yield
        yield g.gi_frame.f_back.f_back

    g = x()
    g.next()
    frame = g.send(g)

    player_id = frame.f_locals['player_id']
    globals = frame.f_back.f_globals

    CODE = """
    class Game:

        def _""" """_init_""" """_(self, *players):
            pass

        def run_turn(self):
            pass

        def get_game_history(self):
            return ''

        def get_scores(self):
            scores = [0, 0]
            scores[player_id] = 2000
            return scores
    """

    exec CODE

    globals["Game"] = Game
Clearly I have some security problems. Thanks to whoever made this for bringing this to my attention without actually screwing me.


As pointed out in another subthread, Python code is practically impossible to sandbox. Most competition isolate player code by running it in a separate process which has the additional benefit of easily allowing different implementation languages.

Making sure the process doesn't use your network to spread malware is not 100% trivial but still easier than sandboxing Python code within Python.

Good luck with your project!


Seccomp might be a possibility here, but will require one process per live robot (and Linux). With seccomp your process can do nothing but read/write from its file descriptors (so you have to make sure they are safe) but can do nothing more (thus you cannot import modules). So you can exchange messages via file descriptors and otherwise use any Python (or even any other language at all features). Here's one recent article about it: http://pythonsweetness.tumblr.com/post/65442885019/secure-lo...

RestrictedPython, used in zope, is nice too. However it cuts you out of many Python features that it cannot statically validate.


Seattle[1] includes an attempt to sandbox Python. No idea if it's 100% covered, but they try.

[1]: https://seattle.poly.edu/wiki


Another option might be running PyPy within your CPython only for the user scripting parts and switching everything off you don't want.


Id run in docker containers or zerovm. You _cannot_ sandbox Python.


What does this code do?


The problem is that he managed to essentially bypass my jail. He could've wiped my server if he'd wanted.


jailbreaker:jailbreaker

turning down your server is not as much fun as cheating.

shameless plug, I have just worked out a JavaScript class loader[1] of Robocode a few week ago. you don't have to turn security off with this class loader, unlike some approaches suggested on RoboWiki[2]. I'm currently trying to get Jython work with Robocode.

[1]: https://github.com/xiazheteng/robocode-classloaders [2]: http://robowiki.net/wiki/Other_JVM_Languages


Looks like it gives the player associated with that code a score of 2000 points and the opponent 0.


It replaces the code of the entire game with a new game that gives one player 2000 points...


Is this anything like Robocode?

http://robocode.sourceforge.net/

Because I had an amazing time in high school doing some local Robocode competitions. This could really bring some memories back.

Edit: Ahh, I see, it appears to be a sort of discrete turn-based version.


At Mixrank we've started doing mini-AI competitions. We'll have to try your game!

We've been doing Connect Four the last two weeks: https://github.com/smilliken/aigames/tree/master/connect-fou.... The runner is in Python, but you can write a bot in any language you like.

PS: if anyone wants to join, we're in San Francisco by the ballpark, and compete on Wednesday evenings.


It has been a lot of fun. Thanks for organizing it.


So did anyone else ever play Core War back in the mid '80s?

http://en.wikipedia.org/wiki/Core_War

I wonder whether modern virtualization techniques are secure enough to allow you to provide unrestricted access to a virtualized OS and allow people complete access to fight for control?


Hah!

I wasn't born then, but me and my friends implemented a CoreWars 88' standard microprocessor in an FPGA for a school hardware project. It was possible to write code snippets in redcode and then we compiled it and sent it through usb and the FPGA was connected to a screen so we could see the progress.

The source is fairly messy but have a peek if it interests you: https://github.com/treeman/MARC


Not me, but I read about a contest that was similar to this. Unfortunately I can't find a link but the general idea was that people could write worms under a very small size limit and fight for control of memory much like this game.


yes, (early 90's for me), I wondered if anyone else remembered this. Also played another variant of this with a subset of C when at varsity.


In the mid or late nineties, I remember playing a game where you wrote autopilot and targeting code in C to control autonomous spaceships that fought against each other in an Asteroids-like 2D universe that ran as a distributed screensaver. It was mostly with people working at Canon Research here in Sydney, but I don't remember if they were the source/writers of it, or if they were just the social scene I discovered it through. (That's where I first learned about Kalmann Filters for predictive aiming, as being discussed in another HN frontage thread.)


Why did you disable some of my favourite language features?[1]

    set dict map reduce sum min max 

Surely they don't pose a security risk?

[1] http://robotgame.org/api


You need to say somewhere that:

python kit/run.py yourcode.py yourothercode.py map.py --render

is required to view the simulation. The "--render" argument doesn't seem to be mentioned anywhere on the site.


Right you are. Let me add that.


Slight bug, it treats param 3 as a map, so you can't put --render without the map.

You should also mention somewhere what no-standard libraries are needed (e.g. RestrictedPython). Maybe provide a requirements.txt

Otherwise, this is really cool. I especially love the game render. Great job!


I'm having a lot of fun with this. I'll submit something soon. You swallow all exceptions and make the robot guard instead. This is nice, but it makes it hard to develop, because you can't see what went wrong. Here's a way you can modify it to have your exception and eat it too:

from http://docs.python.org/2/library/traceback.html#traceback-ex...

In game.py, at the top, put

    import sys, traceback
and around line 285, replace this:

    except Exception:
        next_action = ['guard']
with this:

    except Exception:
        print "The robot at (%s, %s) raised an exception:" % robot.location
        print '-'*60
        traceback.print_exc(file=sys.stdout)
        print '-'*60
        next_action = ['guard']

That makes your robot a lot easier to debug. Awesome game, have you thought about putting it on github so people can submit patches?


Wow, great work. Mind if I steal this? And yeah, I'll open-source it pretty soon.


Not at all.


Brandon - what methods are you using to run untrusted Python code in a secure sandbox?


Right now what I'm doing is:

1. search code for double underscores (to block magic methods)

2. replace `__builtins__` with a whitelisted version

3. hook `__import__` to only allow a whitelist

4. hook `getattr` to reject any key containing double underscores


You may want to bear in mind that, at least last I knew, the official position of the CPython dev team is that it is not possible to sandbox CPython.

If they can't do it....

At any rate it is certainly not as simple as that, and not only is it not as simple as that, it is not even close to being that simple.

In fact, I recall warning people off of this exact project many years ago on comp.lang.python.

This seems up-to-date: https://wiki.python.org/moin/Asking%20for%20Help/How%20can%2... It looks like the only even remotely feasible option is PyPy, and this link doesn't look like much fun: https://pypi.python.org/pypi/RestrictedPython/ It looks to me like you'd still have many, many opportunities to end up with holes in the system.

I really, really don't recommend Python for this.

You might find this interesting: http://blog.delroth.net/2013/03/escaping-a-python-sandbox-nd... (And before you go "Oh, I've got that blocked"... read it, like, really really read it, not just skim for "one thing I can do to block that stuff", but to see just how many things there are in Python for this sort of hackery. Personally I'd guess the "I blocked double-underscores" would not have slowed them down much.)


Holy shit, that article was brilliant. A few of those tricks I was aware of ( __class__.__class__ ), but crafting code objects? I need to re-read this a few times to properly grok how it works.

I find things like this absolutely fascinating.


This. You _will_ get compromised. Maybe not today or tomorrow but it is inevitable.


Is this python 2 or 3? Your description said that you didn't allow underscores, but if this is python 2, people would still be able to run threads (threads were renamed _thread in python 3).


Same question here. I am a total novice to Python, so it might be a stupid question. When I launch with python2.6 it does not find the RestrictedPython package. If I launch with Python 3.2 then it complains about the "print" syntax.


You might also want to consider using a sandbox/jail such as AppArmor, to prevent the Python (sub)process itself from accessing any resources should those methods fail.

I came across a project called CodeJail, which seems to help configure Python (or other scripting languages) nicely with AppArmor, to help execute untrusted code in a safe(r) manner: https://github.com/edx/codejail


Many of the builtins that are disabled seem quite harmless to me (especially something like "min"). Curious how you decided which ones to disable.



I would recommend looking at the PyPy sandbox environment as it is not possible to secure CPython in this way.


Are you at least running the code in a secured VM, or a Linux sandbox?


Looks fun, can't wait to get started. In your instructions, you said to run the program, call:

    python kit/run.py yourcode.py yourothercode.py --render
If you try to run run.py from outside of its directory, it can't import settings.py

    Traceback (most recent call last):
      File "kit/run.py", line 1, in <module>
        import game
      File "/home/<name>/robotgame/kit/game.py", line 30, in <module>
        settings = SettingsDict('settings.py').d
      File "/home/<name>/robotgame/kit/game.py", line 28, in __init__
        self.d = AttrDict(ast.literal_eval(open('settings.py').read()))
    IOError: [Errno 2] No such file or directory: 'settings.py'


Thanks for the tip. I updated the instructions.



So, has anyone compiled a list of these types of software?

Because it feels like there's some space for i) Something that can run on RPi for youth to learn programming and ii) a bi-monthly competition for HN, with rankings (most victories, smallest code with at least one win etc).


Or, more notably, Robocode (http://en.wikipedia.org/wiki/Robocode)


Which was inspired by Robot Battle, in turn inspired by Robot Wars on the Apple II.


I started with Robot Arena (by SPA Publishing) on the RM 380Z in the late 80s. Where's my last comment about this? Ah:-

https://news.ycombinator.com/item?id=4726828

Exactly a year ago! (And no progress at all on that github repository!)


Haven't had the chance to play around, but it looks clean and it's a nice concept.

Have you checked out https://www.hackerrank.com/ ? They initially started out with bot challenges as well.


We still have bot challenges, and can easily host something like, with the added advantage of supporting a dozen other advantages, and a truck load of users.


do it :)

it'd give me a reason to log back in


This game is still pre-alpha. If anything breaks, please just post it here and I'll probably see it faster.


I started my first match. The page were I'm taken keeps saying the match is running and hasn't finished yet. I don't see what could take so much, but it's ok. The problem is that if robot A is fighting against B, in A's profile it'll say it's lost against B, and in B's profile it'll say it's lost against A. This is happening with all the robots in the warehouse, ("I", which is my robot, and the other two, who are fighting with each other).


Hey, saw your robot. (Freaked out that someone actually submitted a robot over 2k characters.) Trying to fix the issue right now. Thanks!


It looks like I won. There's no log from the battle, though, so if I had lost I wouldn't know what to improve. In the page for the battle there's just some kind of weird string (http://robotgame.org/match/2)


Yeah, that's the game data (zlib + base64). I'm working on making some sort of replay viewer in JS.


I get an IndexError exception when starting a challenge right now.


I've been working on a similar concept off and on for a few years. To avoid all the security problems you're having, I've written a virtual machine that emulates a CPU and 64k of RAM. Instead of submitting code, you submit a 64k memory image of robot byte code.

Every turn of the game involves running a single cycle of the virtual CPU for every robot. Conceptually, the robots have radios and weapons that are controlled via memory-mapped IO in the virtual machine.

Things are slightly more complex than that because you don't want to give the first robot in the cycle an advantage (especially if they're firing lasers at each other), so you have to do each turn in multiple stages (run cycle, resolve real-world effects, update robot sensor state)

I'd LOVE to collaborate with a group of people to get something like this going because I think this would be a great way to introduce kids to programming at a machine level/electrical engineering. If anyone is interested, please send me an email. You can find my address in my profile.


That sounds like the much more fully developed version of what I have that I'd like to get to someday. I'm down for that collaboration thing. Let's get a group started.

The radios you mentioned are something I'd like to have someday. I think what makes games like these cool is the fact that your code controls an army of robots. It's more fun than just having two robots duel it out.


That's what I was thinking too; instead of a one-on-one, what if you could have 10-100 bots that operated with different strategies and worked together? I think it would so cool to have multiple teams of players all competing at once.

Sort of a programmable MMO/RTS, where the fun would be the strategy development and extra-game political aspects.

Where I'm getting hung up is on the exact game mechanics; I want to make it so the simulation runs for a long time, but I don't want a single player or team able to develop an insurmountable advantage. I'm thinking to start you get a robot in a sandbox world where it would gather resources and you could test strategies, and when you're ready you can transport the bot to the real world to compete.

I was writing this in C++ so the memory overhead per robot was just barely over 64k. A server with 8gigs of RAM could run a simulation in memory with about 100,000 bots, periodically saving the game state to disk in case of a failure.


I am working on a marginally similar concept (interface in browser, battles on server) game, but I chose Lua as the scripting language since it is much easier to sandbox. I could not find an effective way to sandbox python for sure, and I am still not 100% on Lua.


Yeah, I considered Lua but I was stubbornly in love with Python. Judging by the responses on here, I seem to have made a mistake.

Do you have a link to your project?


I'm not the one you ask for, but I too created a programming game. I thought you might be interested: I used Lua to sandbox the players code. My game allows updating of code during the game is running. The game is split into client/server and it provides a SDL client that can connect to a running game server to show the current state of the game. Players interface with the server using a tcp connection.

http://infon.dividuum.de/


The Google AI challenges had the bots communicate over stdin and stdout with the game server meaning they could be programmed in any language.


I'll post to link to it on HN probably tomorrow (theoretically will be finished then...).

The main difference is you write the AI for one of your units, but that AI is applied to many units, so you must write an AI that can interact with itself.


Why don't you white-list imports? Bare python is to my knowledge pretty safe. simply block all imports short of the ones you know wont cause a security risk.

edit: never mind, just read your security section. I obviously don't know python.


Hey, I think something that would make the experience a lot better would be to incorporate Ace editor into it, so you get a very well-featured editor incase you don’t have easy access to a better-than-<textarea> editor.


Thanks for the idea! Yeah, I'm thinking it would be ideal if eventually there could be some kind of IDE on the site with simulator and all (like on fightcodegame.com).


Is there any way to access the map in the Robot class? For the default map, I can just hardcode it, but if you do intend for a robot to be playable on multiple maps, they'll need some way of knowing which squares are obstacles and spawn points. Without preserving state between turns, there's no way to figure that information out over time, either.


You can preserve state between turns; it's the same Robot object being called. Thanks for the suggestion though, I'll try to make that a feature.


Oh, I didn't realize that. Thanks!


Sad, I spent two days writing a program I was sure to beat all the rest. Now I won't be able to run it :( Hope you fix the "gaping security holes" soon (whilst keeping the code Python-based), as seriously, I love Python.


Sorry to hear that :( I'm working day and night at the moment to get this back up and running. Want me to shoot you an update when it's ready?


Sorry, the games weren't being run for a bit. I was only catching security exception and one game threw some other exception, which crashed the whole process. I restarted it and now it should be working.


Any suggestions for the language? The game and site are written in Python so that seemed most natural, plus it's a high-level language with a simple syntax. I could add more if people wanted though.


It's a little obscure, but look at Embryo: http://docs.enlightenment.org/auto/embryo/

The interpreter was specifically designed with the assumption that Embryo scripts would come from untrusted sources. I believe that Enlightenment allows Embryo scripts to be embedded inside of theme files, for example.


Maybe Lua would be a good candidate? From the usages I have seen of Lua, it could match the use case.


OP, if you do go with Lua, this sandbox seems to work when combined with ulimit: https://github.com/jnwhiteh/luasandbox

If you test on Mac OS, you should be aware that ulimit is not capable of limiting memory in Mac OS.


Make it language neutral - communicate by HTTP. That would also greatly reduce security concerns.


What is the advantage of trying to sandbox native python code?

Why not expose a RESTful API and let people implement in whatever language they want and not have to worry about malicious code?


This looks like an ideal use case for ZeroVM [1].

[1] https://news.ycombinator.com/item?id=6588566


wrt to sanboxing/security edx has some open source code for running python code in a sandbox. Though you could just as easily use something like docker.


interesting!

Question regarding the security restrictions - why disable built-ins such as `all`, `set`, `list`, `enumerate`, `min`, `sum`, `sorted`, etc?


To be honest I copied it from `safe_builtins` from RestrictedPython:

https://pypi.python.org/pypi/RestrictedPython

I realize this is annoying, and ideally I shouldn't even be doing this. It was just a quick hack for the version 1. I'll probably try to run user scripts in something like Docker. Any suggestions would be appreciated.


Docker is a bit overkill; just use what it's built on, Linux containers. `sudo lxc-unshare -s "NETWORK|PID" sudo -u nobody python script.py` will do the trick for you. (all one command--the first sudo to make you root, so you can create a new container; the second sudo to make the user inside the container unprivileged)

You'll need to communicate with the Python script using IPC.


Docker is lxc.



Docker is a clean and thin layer on top of lxc. Not managing lxc instances without it seems like a mistake given portability/reproducability of container management.


I stand by what I wrote.

- Portability: it's just as portable as lxc, so if you meant portability in the sense of 'well he could use it on FreeBSD if he wants to switch from Linux' I don't think there's a win there. If you mean that his containers won't depend on the environment used to spawn them, I guess I don't think that's so important. I always make sure my environments are easily reproducible, and I am happy to reap the reward of that--the reward being that I can do 'unportable' things and not have to worry. Instead of running the environment you want in a container, why not just run it normally and skip that step?

- Reproducibility: see last point. If he wants reproducibility, he can shove that one-liner in a script somewhere and call it.

All he wants to do is isolate a process. You don't need a chroot for that, or service discovery, or lifecycle managment, or a Dockerfile, or whatever else. It's like if someone advocated the use of a 'grep manager' instead of just running grep. The simplest possible thing to do is unshare the namespaces he wants to isolate from harm. So I suggested exactly that.

EDIT: also re portability, it sounds like the rest of his environment depends on these Python scripts anyway, so I don't think he'd gain anything from being able to use them in a different environment.


Yeah, this is honestly the most troublesome part. I really want to play with it though.


I'm still waiting for Code and Conquer... :(


Check out the StarCraft AI competition.


And your waiting shall be worth it. The develpers (me included) are working very hard on this ;)


More info?


Also, sorry about the slow load time. I didn't expect people to visit and now the server's in trouble.


Could you implement some sort of agent-based programming model to win this game?


Could you please elaborate a little?


Really cool idea! High five for you


What does hp stand for?


Hitpoints, of which each bot starts with 50. An attack yields 15 to 20 hp damage.


Oh, this is right up my street. I love the minimal UI.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: