Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IFrame Startup Time Counts Against WallClock AND Fix Security Bug #55

Open
anonyco opened this issue Jan 8, 2019 · 2 comments
Open

Comments

@anonyco
Copy link

anonyco commented Jan 8, 2019

Thank you devs for setting up Battlecode. I was observing how the code runs, and unfortunately, it appears as though initial startup code evaluation time counts against the allotted execution time for the bot. One possible fix is changing eval to Function and passing three parameters like so. This will allow the time the code starts to be recorded inside the code itself. Then, Object.freeze will prevent tampering with this number.

The security bug is that the robot can use window.parent and window.top to access the global namespace and communicate with other robots instantly and sabotage the other team. The solution is to delete window.parent and delete window.top to prevent access

function runCode(codeString, wallClockReference){
    // wallClockReference is an array whose first index will be set to the time now
    var iframeElement = document.createElement("iframe");
    iframeElement.width = iframeElement.height = "0";
    iframeElement.setAttribute("style", "border-width:0px");
    document.body.appendChild(iframeElement);
    codeString = '"use strict";arguments[0][0]=arguments[1].now();arguments[2](arguments[0]);' + codeString;
    var ctxWindow = iframeElement.contentWindow;
	var timeObj = [];
    // patch security bugs: //
    delete ctxWindow.parent;
    delete ctxWindow.top;
    ///////////////////////////
    var resultingValue = ctxWindow.Function(codeString).call(
        ctxWindow, // `this`
        timeObj, // arguments[0]
        performance, // arguments[1]
        Object.freeze // arguments[2]
    );
	wallClockReference.push(timeObj[0], performance.now()); // use Array.prototype.push to reduce delay
    document.body.removeChild(iframeElement);
    return resultingValue;
}

Observe the difference using the test code below.

(function(){
    var startTime = performance.now();
    var val = [];
    runCode('for(var i=0;i<128;i++);'.repeat(4096) + 'console.log("Hello World")', val);
	var endTime = performance.now();
	console.log("Timing the way it is now:    " + (endTime - startTime));
	console.log("Timing the way it should be: " + (val[1] - val[0]));
     ;
	
})();

As seen, without this optimization, the user's granted execution time can in some times be halved. I do not know about you, but I for one do not believe that code parsing time should count against you. Rather, only code startup time and execution time should count against you.

@anonyco anonyco changed the title IFrame Startup Time Counts Against WallClock IFrame Startup Time Counts Against WallClock AND Fix Security Bug Jan 8, 2019
@npfoss
Copy link
Contributor

npfoss commented Jan 10, 2019

This is a great find, thanks! It looks like you've even modified the code to fix the issue, could you submit that as a PR please? I'll just be easier for us to review as a diff and then one-click approve.

@Cognitoco
Copy link

Cognitoco commented Jan 10, 2019

(I am AnonyCo on a different machine)

Yes, you are correct that I designed my code to be similar to BattleCode's actual code. However, the trouble is that it is not actually very similar to the real code. For me to apply the code above to BattleCode's real code would take many hours that I do not have because I am spending all of what little time I have (full time high school junior) to work on the robot I am entering into this years competition. Maybe, I might be able to get to it on the weekend. Anyways, thank you for responding to my post above so quickly. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants