AS3验证套接字主机连接 - 解析主机?

时间:2014-07-12 21:46:23

标签: actionscript-3 sockets dns host resolve

我遇到了一个问题,人们通过使用本地HOST文件来操纵游戏客户端套接字的连接。也就是说,我有一些类似于

的方法
    private var _socket : Socket;
    public function init(host : String, port : uint = 0) : Boolean {
        _socket.connect(host, port);
        return true;
    }

我希望主持人总是像“例如.game.com'”这样的东西,并且总是要解决一些ip' 255.255.255.255'。但是,通过使用HOST文件,有可能是' example.game.com'解析为#127; 127.0.0.1',允许第三方应用程序拦截和修改游戏数据。

它的骗子是我不能使用DNSResolver,因为这需要AIR,解决方案必须是纯ActionScript。我也不能相信某个外部JS / PHP脚本的请求会为我解决它,因为这可能会被一些HTTP代理(e.x. Fiddler)修改

有没有人有任何纯粹的AS3解决方案可以让我确保我的套接字连接的主机是我想要的?

1 个答案:

答案 0 :(得分:0)

我可以想到两种方式。

首先,从初始测试开始,您可以查询remoteHost和remotePort。即使您使用主机,它们也会返回对您有用的值。如下所示。

其次,您可以将套接字设置为ping Flash,以便每隔约5分钟左右获得一次响应。 ping请求localAddress,localPort,remoteAddress和remotePort。如果它们与您收到数据时的预期不符,请终止连接。

最重要的是,无论何时收到数据,都要在服务器端进行验证。让您的服务器了解玩家正在做什么,以及什么是合理的。 Mos多人游戏(我认为这是),在服务器上有效地“运行”。因此,如果用户A设法绕过你设置的安全性并说他想要在5000码外击中目标造成150万的伤害,那么服务器就已经知道了:

  • 他超出范围
  • B他不能做那么多伤害

在开发最终游戏时,这个主题是最难管理的主题之一。虽然你可以与它竞争,而且大部分都是胜利,但你永远不会阻止人们模仿'服务器并在那里使用你的内容。但是,你应该能够阻止大多数注射进入你的游戏。

编辑:当人们开始反编译SWF并设法重新编译它时,您的问题才真正开始。然后,任何客户端验证都不在窗口中,因为它们将删除您已有的验证,并且您在服务器端验证时100%依赖。这也可以通过内存编辑来实现,但是......通常,客户端验证只会阻止更基本的“黑客”。

package kazo 
{
    import flash.net.SharedObject;
    import flash.net.Socket;
    import flash.events.Event
    import flash.events.ProgressEvent
    import flash.events.SecurityErrorEvent
    import flash.events.IOErrorEvent
    /**
     * ...
     * @author KM
     */
    public class TestCases 
    {

        private var socket:Socket;

        private const ADDRESS_LIST:Vector.<String> = {
            '255.255.255.255',
            '255.255.255.254'
        }
        private const PORT_LIST:Vector.<String> = {
            '111',
            '112'
        }

        public function TestCases() { }

        /**
         * Start the test case
         */
        public function start():void {
            trace('Starting test case');

            socket = new Socket();

            socket.addEventListener(Event.CONNECT, onConnect);
            socket.addEventListener(ProgressEvent.SOCKET_DATA, onData);

            socket.connect('example.domain.com', port);
        }

        /**
         * 
         * @param   e
         */
        private function onConnect(e:Event):void {
            trace(socket.remoteAddress);
            trace(socket.remotePort);

            // validate before doing anything
            validateNow();
        }

        /**
         * 
         * @param   e
         */
        private function onData(e:ProgressEvent):void {
            trace(e.target);

            // validate before processing data
            validateNow();
        }

        /**
         * 
         */
        private function validateNow():void {
            var i:int = 0;
            // List of allowed ports (MUST be hardcoded)
            var portLen:int = PORT_LIST.length;
            // List of addresses (MUST be hardcoded)
            var addressLen:int = ADDRESS_LIST.length;

            var addressPass:Boolean;
            var portPass:Boolean;

            // Loop through, make sure we're valid
            for (i; i < portLen; i++) {
                PORT_LIST[i] === socket.remotePort ? portPass = true : continue;
            }

            // Loop through, make sure we're valid
            for (i = 0; i < addressLen; i++) {
                ADDRESS_LIST[i] === socket.remoteAddress ? addressPass = true : continue;
            }

            // If we're not, close off. If we are, run the course
            if (!addressPass || !portPass) {
                socket.close();
                // inform server
            }
        }

    }

}