101 comments

[ 3.4 ms ] story [ 161 ms ] thread
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.
Also, sorry about the slow load time. I didn't expect people to visit and now the server's in trouble.
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).
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.

Yeah, this is honestly the most troublesome part. I really want to play with it though.
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.

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).

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.
Maybe Lua would be a good candidate? From the usages I have seen of Lua, it could match the use case.
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.

Make it language neutral - communicate by HTTP. That would also greatly reduce security concerns.
Really cool idea! High five for you
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

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

Many of the builtins that are disabled seem quite harmless to me (especially something like "min"). Curious how you decided which ones to disable.
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.)

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

Obvious samefag is obvious. Go back to 4chan kthxbai.

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.

I would recommend looking at the PyPy sandbox environment as it is not possible to secure CPython in this way.
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.
Are you at least running the code in a secured VM, or a Linux sandbox?
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

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!

Oh, this is right up my street. I love the minimal UI.
(comment deleted)
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?

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.)
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

does anyone have any ideas on where I can learn to do this properly?

I am new to programming, I've completed the code academy python course but don't really know where to start.

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 ;)
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.
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?

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.

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/

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.

The Google AI challenges had the bots communicate over stdin and stdout with the game server meaning they could be programmed in any language.
Could you implement some sort of agent-based programming model to win this game?
Could you please elaborate a little?
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.
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.

Another option might be running PyPy within your CPython only for the user scripting parts and switching everything off you don't want.
What does this code do?
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...
The problem is that he managed to essentially bypass my jail. He could've wiped my server if he'd wanted.
Id run in docker containers or zerovm. You _cannot_ sandbox Python.
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!
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.
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.