ADOBE/ ActionScript

액션스크립트 flex Flash Socket 이용 시 소켓 보안문제인 <policy-file-request/> 문제 해결방법 소켓통신 보안 해결 관련

AlrepondTech 2014. 1. 17. 14:54
반응형

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


출처: http://mudchobo.tistory.com/504

[Flex] Flash Socket 이용 시 소켓 보안문제인 <policy-file-request/> 문제 해결방법

많은 분들(?)이 제 블로그에 오셔서 질문을 해주셔서 간단한 예제를 통한 설명을....-_- 나중에 저도 참고하려고 기록용-_-

일단, Flash에서 CrossDomain에 걸리는 데이터를 요청할 때 Plicy File인 crossdomain.xml 파일을 root에 정의해둬서 해당 도메인이면 데이터를 허용하게 할 수 있습니다.

소켓도 마찬가지입니다. 해당 도메인에서 해당 포트로 들어온 요청은 받겠다는 정책파일을 작성할 수 있습니다.
최초 소켓이 정책파일을 요청하게 되는 포트는 843포트입니다. 만약 이포트가 열러있지 않다면 현재 연결하려고 하는 포트로 <policy-file-request/>를 날려서 정책파일을 요청하게 됩니다.
그러면 843이든, 해당포트든 간에 정책파일만 날려주면 됩니다.

[code]<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
   <allow-access-from domain="*" to-ports="10000-10001" />
</cross-domain-policy>[/code]
소켓에 대한 정책파일을 정의한 것인데, domain에는 허용할 도메인을 쓰고, to-ports에는 허용할 포트를 쓰면 됩니다.
이걸 날려주면 이제 연결할 포트로부터 데이터를 주고 받을 수 있습니다.

초간단 에코예제!
일단 서버는 자바로...(그나마 자신있는 언어라서ㅠㅠ)

일단 PlicyFileServer를 하나 돌릴 쓰레드를 만듭니다.
PlicyFileServer.java
[code]import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;


public class PolicyFileServer extends Thread{
   
    private ServerSocket serverSocket;
    private String policyFile = "<?xml version='1.0'?>" +
                                "<!DOCTYPE cross-domain-policy SYSTEM '/xml/dtds/cross-domain-policy.dtd'>" +
                                "<cross-domain-policy>" +
                                "<allow-access-from domain='*' to-ports='10000' />" +
                                "</cross-domain-policy>";
   
    @Override
    public void run() {
        try {
            serverSocket = new ServerSocket(843);
            while (true) {
                final Socket socket = serverSocket.accept();
                new Runnable() {
                    @Override
                    public void run() {
                        try {
                            socket.setSoTimeout(10000);
                            InputStream in = socket.getInputStream();
                            byte[] buffer = new byte[23];
                            if ( in.read(buffer) != -1 && (new String(buffer)).startsWith("<policy-file-request/>") ) {
                                OutputStream out = socket.getOutputStream();
                                out.write(policyFile.getBytes());
                                out.write(0x00);
                                out.flush();
                                out.close();
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        } finally {
                            try { socket.close();} catch(Exception ex){}
                        }
                    }
                }.run();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
[/code]
내 용을 보면 그냥 서버소켓하나 만들어서 요청이 들어오면 그 소켓으로 policy file을 전송하는 형태입니다. 파일은 만들기 귀찮아서-_- 그냥 String으로 선언-_- 보면 모든도메인에 한해서 10000포트를 열어주는 겁니다.

이제 메인서버!
SocketTest.java
[code]import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;


public class SocketTest {

    private ServerSocket server;
   
    public SocketTest() {
        try{
            server = new ServerSocket(10000);
            System.out.println("접속을 기다립니다.");
           
            while (true){
                final Socket socket = server.accept();
                Thread t = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF-8"));
                            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
                            String line = null;
                            while ((line = br.readLine()) != null) {
                                System.out.println("수신데이터 : " + line);
                                pw.println("Hello! " + line);
                                pw.flush();
                            }
                        } catch (Exception e) {
                            try { if(socket != null) socket.close(); } catch (Exception ex) {}
                        }
                    }
                });
                t.start();
               
            }
        } catch(Exception e){
            System.out.println("Error!");
        }
    }
   
    public static void main(String[] args) {
        new PolicyFileServer().start();
        new SocketTest();
    }
}[/code]
데이터를 받으면 다시 Hello!를 붙여서 다시 전송해주는 echo서버를 하나 만듭니다.
그리고 main함수에서는 PolicyFileServer쓰레드를 하나 시작하고, EchoServer를 돌립니다.

이제 Flex!
[code]<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
               applicationComplete="application1_applicationCompleteHandler(event)">
    <fx:Script>
        <![CDATA[
            import mx.events.FlexEvent;
           
            import spark.components.mediaClasses.VolumeBar;
           
            private var socket:Socket;
           
            protected function application1_applicationCompleteHandler(event:FlexEvent):void
            {
                socket = new Socket("127.0.0.1", 10000);
                socket.addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
                socket.addEventListener(Event.CONNECT, connectHandler);
            }

            protected function btnSend_clickHandler(event:MouseEvent):void
            {
                // TODO Auto-generated method stub
                socket.writeUTFBytes(inputMessage.text + "\n");
                socket.flush();
            }
           
            private function connectHandler(event:Event):void
            {
                trace("접속완료!");   
                hbox.visible = true;
            }
           
            private function socketDataHandler(event:ProgressEvent):void
            {
                var message:String = socket.readUTFBytes(socket.bytesAvailable);
                trace("수신메세지 : " + message);
                textResult.text = message;
            }

        ]]>
    </fx:Script>
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>
   
    <s:layout>
        <s:VerticalLayout />
    </s:layout>
   
    <mx:HBox id="hbox" visible="false" width="100%" horizontalAlign="center">
        <s:TextInput id="inputMessage" />
        <s:Button id="btnSend" label="송신하기" click="btnSend_clickHandler(event)"/>
    </mx:HBox>
   
    <mx:Text id="textResult" width="100%" textAlign="center"/>
</s:Application>
[/code]
Socket 만들어서 10000포트로 연결합니다. 그러면 도메인이 다르게 되면 swf가 843포트로 "<policy-file-request/>"를 날려서 정책파일을 달라고하는데, 서버에서 만들어놓은 PolicyFileServer가 정책파일을 내려주면 받게되면 10000포트로 다시 연결해 연결을 시작하게 됩니다.

몬가 별거 없는데 장황하게 설명해놨네.

그리고, 이런식으로 PolicyFileServer를 서버어플에 통합하면 안되겠죠? 나중에 서버어플이 늘어난다면 계속 새로 추가해야하니, PolicyfileServer를 따로 만들어서 띄워놓으면 되겠죠?^^
일단, 여러 폴리시서버 예제는 구글링하면 많이 나와요~
여기 아래주소는 Java, PHP, C#, VB.NET, Python 등등 예제가 있어요.
http://code.google.com/p/assql/wiki/SecurityInformation
이건 c로 만든거!
http://panzergruppe.hp.infoseek.co.jp/fspfd.html


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


출처: http://streammx.tistory.com/8

[Flex] Flash Socket 이용 시 소켓 보안문제인 <policy-file-request/> 문제 해결방법


플래시 보안의 기본개념 - 센드박스 보안

 

     - 센드박스란 같은 상자안의 모래상자에는 보안이 필요없고, 다른 상자안에 있는 모래와는 보안을 해야하는 개념.

     - 샌드박스 보안이 플래시에 적합한 이유는 샌드박스 개념이 도메인 이름과 연관 관계를 가지고 있기 때문.

     - 다음과 같은 경우에 있어서 서로 다른 샌드 박스로 인식함.

 

          http://example.com

          http://www.example.com

          http://store.example.com

          https://www.example.com

          http://192.0.34.166

 

          해당 주소 중 유념히 살펴봐야 할 부분이 http 와 https 프로토콜이다. 같은 서버있지만 서로 다른 샌드박스로

          인식하고 있다는 것이다. 흔히 개발자들은 '사용하고자 하는 데이터가 다른 서버에 존재할 때만 보안문제가 발생한다'

          라고 알고있다. 그러나 플래시에서는 '프로토콜이 다를 때도 보안문제가 발생할 수 있다'라는 걸 알 수 있다.

 

플래시 보안 4대 요소

 

     - Adobe : Adobe - Flash Player 설정 관리자 - 전역 보안설정 패널 

     - 사용자 : Adobe - Flash Player 설정 관리자 - 전역 보안설정 패널 

     - 사이트 운영자 : crossdomain.xml, html( allowNetworking )

     - 플래시 개발자 : Security.allowDomain("example.com"), LoaderContext.checkPolicyFile = true;

 

Security 클래스 함수 및 속성

 

     - sandboxType : String

        샌드박스 데이터형 반환.

 

     - exactSettings : Boolean

        도메인 체크 방식 기본 'true'로 설정하는게 좋음. 'false'이면 'www.sample.com' 을 'sample.com'으로 인식.

        도메인을 등록하는 allowDomain과 allowInsecureDomain 함수에 적용.

 

     - allowDomain( ..domains ): void

        해당 도메인들을 허가해주는 Cross-Script 핵심문구. 외부서버에 있는 SWF파일 로드 시 사용.

 

     - allowInsecureDomain( ..domains ): void

        해당 도메이들을 security=false해서 https방식으로 보안.

 

     - loadPolicyFile( url: String ): void

        도메인 허가를 외부 보안 정책 xml로부터 허가. 외부서버에 있는 데이터파일( xml, text ) 로드 시 사용.

 

     - showSettings( panel:String = "default" ): void

        보안 정책 관련 셋팅 화면 표시.

 

HTML에서 원격 보안

 

     <object>

          <param name="allowNetworking" value="none" />

          <embed>

               //생략

          </embed>

     </object>

 

     allowNetworking 파라메타에 추가할 수 있는 값.

          - all( default )      network 관련 명령어 모두 사용 가능.

          - internal             다른 사이트로 이동하는 브라우저관련 명령어만 사용 불가.

          - none                모든 network 기능 불가. SWF-SWF간 통신 불가.

 

Loader 클래스와 LoaderContext 클래스

 

     Loader 클래스는 이미지 파일과 swf 파일을 로딩한 후, DisplayObjectContainer에 삽입이 가능한 DisplayObject.

     LoaderContext 클래스는 Loader 클래스를 사용할 때 보안샌드박스 관련 제어를 하도록 3개의 속성을 지원.

 

     - checkPolicyFile: Boolean = false

        기본 'false' 설정.

        로딩전 cross-domain.xml(보안 정책 파일) 보안 정책 파일 체크 여부.

        외부 서버에 있는 이미지 파일을 로드하기 전에 먼저 보안 정책 파일이 있는지 여부를 먼저 체크 후 이미지 로딩.

        보안 정책 파일이 없거나, 설정이 false인 경우 외부 서버에 있는 이미지 로드 시 보안에러 발생.

 

     - applicatioinDomain : ApplicationDomain = null

        SWF파일을 다운로드하는 경우에만 유효한 속성.

        응용 프로그램 도메인은 보안을 위한 것이 아니며 서로 관련된 ActionScript 코드 단위를 관리하기 위한 것입니다.

 

        예제)

        kor 과 en 이라는 폴더에 같은 파일명( Sample.as )의 클래스가 있다고 했을 때 메인에서 이 두파일을 로드하게 되면

        서로 같은 클래스명을 갖고 있기 때문에 마지막로드된 클래스로 속성 및 메서드가 대체되는 문제가 발생합니다.

        이 때 LoaderContext.applicatioinDomain = new ApplicationDomain(); 새로운 도메인을 설정해주어 여러 클래스를

        구분해주면 해결됩니다.

 

     - securityDomain: SecurityDomain = null

        SWF파일을 다운로드하는 경우에만 유효한 속성.

 

        보안 도메인을 선택하는 이유

        첫째 - 로드하는 SWF 파일이 같을 경우.

        자신의 도메인에서 SWF 파일을 로드하면 파일이 항상 자신의 보안 도메인에 배치됩니다.

 

        둘째 - 다른 도메인(다른 서버)일 수 있는 SWF 파일을 로드하는 경우에만 의미가 있음.

        다른 도메인의 SWF 파일을 로드할 때는 두 가지 옵션이 있습니다.

 

        로드되는 SWF 파일이 로드하는 SWF 파일의 보안 도메인과 다른 "고유의" 보안 도메인에 배치되도록 할 수 있으며,

        이는 기본 옵션입니다.

        다른 옵션은 myLoaderContext.securityDomain을 SecurityDomain.currentDomain으로 설정하여 로드되는

        SWF 파일이 로드하는 SWF 파일과 같은 보안 도메인에 배치되도록 지정하는 것입니다. 이를 '가져오기 로딩'이라고 하며,

        보안을 위해 로드되는 SWF 파일을 자신의 서버로 복사한 다음 로드하는 것과 같습니다. 가져오기 로딩에 성공하려면

        로드되는 SWF 파일의 서버에 로드하는 SWF 파일의 도메인을 신뢰하는 정책 파일이 있어야 합니다.



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


출처: http://butterguy.tistory.com/category/AS3.0%20Cookbook/%EC%86%8C%EC%BC%93%20%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D



[ 소켓의 활용 ]
1. 소켓연결은 데이터 전송이 이루어진 다음 자동으로 종료하지 않는다.
2. 클라이언트의 요청이 없더라도 데이터를 Push한다.
3. 주로 멀티유저 어플리케이션에 이용한다.
   
[ 소켓의 종류 ]
1. XMLSocket 
    * 텍스트 기반
    * 실시간 채팅 시스템과 같이 지연 시간이 낮아야 하는 클라이언트 서버 응용 프로그램에 유용
    - XML 메시지는 전이중 TCP/IP 스트림 소켓 연결을 통하여 전송됩니다.
    - 각 XML 메시지는 완전한 XML 문서이며 0바이트로 끝납니다.
    - 단일 XMLSocket 연결에서 송수신할 수 있는 XML 메시지의 수에는 제한이 없습니다.
    
    * XMLSocket.connect() 메서드는 1024 이상의 TCP 포트 번호에만 연결
      ( 1024보다 작은 포트 번호는 주로 FTP, Telnet, HTTP 등과 같은 시스템 서비스에 사용되므로, 
         보안 문제 때문에 XMLSocket 객체가 이러한 포트를 사용하지 못하도록 차단 )
     
2. Socket 
    * 바이너리 소켓(메일서버 , 채팅서버 등의 원격제어)
    * ActionScript 코드를 활성화하여 소켓 연결을 만들고 원시 이진 데이터를 읽고 쓸 수 있도록 합니다. 
    * XMLSocket과 유사하지만, 수신된 또는 전송된 데이터의 형식을 지정하지는 않습니다. 
    
[  보안정책 ]
    - swf와 호스트는 같은 도메인에 있어야 한다.
    - 네트워크에 있는 swf는 로컬서버에 접근할 수 없다.
    - 허용되지 않은 swf파일은 어떠한 네트워크에도 접근할 수 없다.
    - 크로스 도메인접근을 허가하거나 1024포트이하에 연결하는 경우 크로스도메인 정책이 필요



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



보안문제를 해결해주면 되겠지요?

<?xml version='1.0'?><cross-domain-policy><allow-access-from domain='*' to-ports='*'/></cross-domain-policy>

위를 복사해 두세요.




출처:http://kuimoani.tistory.com/48?srchid=BR1http%3A%2F%2Fkuimoani.tistory.com%2F48


보안정책이 하도 수시로 바뀌어서 검색을 해봐도 뭐가 최신버전인지 당최 모르겠다...

심지어 Adobe나 Silverlight 레퍼런스 사이트에 가도 해당 설명에 대한 명쾌한 해답이 없어서 걍 내가 직쩝 짜서 정리해봤다...



Flash(Flex) Socket 보안 정책

Flash로 소켓통신 이용시 보안 sandbox문제 해결방법을 검색해보니 참으로 많은 아티클이 있었다. Security.loadPolicy("http://IP/crossdomain.xml"); 을 선언하라던지 
swf파일이 있는 웹경로 루트에 crossdomain.xml파일을 두라던지 
843port로 인증용 소켓서버를 만들라던지... 

결론은 걍 해당 소켓서버가 클라이언트swf에서 보낸 <policy-file-request/>를 받으면 crossdomain.xml의 내용을 send해주고 소켓을 끊으면 되는거였다. 그러면 클라이언트swf가 자동으로 다시 connect를 요청하며 정상동작이 된다. 
Security.loadPolicy를 이용하거나 웹경로 루트에 crossdomain.xml 파일을 두는것은 소켓 보안은 해결되지 않았다. 843 port에 인증서버를 두는것은 아직 안해봤지만 이건 될것같다. (실버라이트가 같은방식으로 943포트를 이용하므로 분명 flash의 보안방식을 베꼈을것 같으므로..)




Silverlight의 보안 정책

위에서 말했지만 Sliverlight의 소켓보안정책 해결법은 한가지 뿐이다. 943port에 인증용 소켓서버를 만들어야 하는것이다. flash와 마찬가지로 클라이언트xap이 메인서버에 접속하기 전에 같은 도메인(혹은 IP)의 943port에 접속을 시도한다. 접속되면 서버에게 <policy-file-request/>를 보내고 서버는 클라이언트에 clientaccesspolicy.xml 의 내용(MSDN에선 clientaccesspolicy.xml이 없으면 crossdomain.xml의 내용을 전송해도 된다고 하는데 실제로 해보진 않았다. 믿을 수가 있어야지!!!)을 전송하면 클라이언트xap이 자동으로 연결을 끊고 메인서버에 재접속을 시도한다.

그리고 또 한가지는 Silverlight에서 소켓통신으로 사용할 수 있는 port 범위가 제한되어 있다는거다. 일부 사이트에서는 4530-4532 port 라고 설명되었던데 아마도 구스리의 소켓통신 예제에서 사용된 소켓범위가 와전된것 같다. 실제로는 4502-4534 범위의 포트만 사용할 수 있다.






지금이야 많은 관련글들이 있어서 비교적 쉽게 해결할 수 있지만 처음 Flash가 socket통신에 보안 sandbox를 구현했을때는 아무런 설명이나 공지가 없어서 정상동작 하던 어플리케이션들이 에러발생도 안했는데 접속이 안되는 문제가 발생해서 꽤 애를 먹었던 것이 기억난다.
지금도 Flash나 Siverlight나 보안문제로 인한 미동작에 아무런 에러표시를 하지 않아서 원인 찾기가 매우 어려운 실정이다. 






※ 어쨌든 보안문제로 인해 동작을 못한 싸이월드 채팅을 이번 글도 정리할겸 소스를 수정해서 다시 오픈하게 되었네요.. 다음엔 Flex로 만든 싸이월드 채팅을 Siverlight3로 포팅해서 오픈해볼까 생각중입니다..




/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


출처: http://blog.naver.com/PostView.nhn?blogId=karasmonster&logNo=151592863


[AS3.0] Socket 통신 시도시, Policy (crossdomain.xml) 관련 설정 내용.



업무 중...

HTTP Request Header 에 특정 내용을 담아서 보내야 하는데,

그 타입이 커스터마이징 된 것이 아니라, 기본 헤더값 중에 하나에 보내달라는 요청이 있었다.


그리하여 정신을 놓고 있었는데, C 개발자인 요청했던 팀 중 한 대리 분이

소켓 통신을 이용해서 직접 하드코딩하여 보내는 법이 있다고 한다.


하여, 학교 다닐 때 데이터통신 과목을 망치면서 전혀 못 알아 듣게 된 소켓이니..하는 내용을 

찾아가며 이러저러 삽질을 하고 나니.

안된다. ㅠㅠ


하여, 관련 내용을 찾아서 며칠 간 헤매고 다닌 결과를 공유.


1. 소켓 통신을 위해서 플래시 쪽에서 서버에 요청을 한다.

2. 플래시 플레이어 보안 정책 상, 서버측에서 접근할 수 있는 권한을 정의한 정책 파일이 필요하다.

3. 해당 파일은 HTTP 통신의 경우 도메인 최상위에 crossdomain.xml 로 존재한다.

4. 소켓용 설정 내용에선 to-ports 등의 태그 내용이 포함되어 있으며, 관련 내용과 스펙은

   http://www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html

   에서 상세하게 확인할 수 있다.

5. 최초 접속을 위하여 소켓이 요청할 때 사용되는 포트는 IANA 와의 협약에 의해서 

   843번 포트로 정해져 있으며, 그 내용은 <policy-file-request/> 와 같다.

6. 위의 5항과 같은 요청이 도착한 경우 서버는 

   <?xml version="1.0"?>

   <!DOCTYPE cross-domain-policy SYSTEM "/xml/dtds/cross-domain-policy.dtd">

   <cross-domain-policy>

      <allow-access-from domain="*" to-ports="10000-10001" />

   </cross-domain-policy>

   와 같은 내용을 보낸다.

   여기서 to-ports 항목은 사용가능하도록 설정할 포트를 뜻한다.

7. 위의 6항과 같은 내용을 전달 후에, 서버는 소켓 연결을 해제해야 한다.

8. 이후, 플래시는 허용된 포트로 접속하여 소켓 통신을 진행한다.


위와 같다.

보안 정책 때문이긴 한데... 몰라서 정말 많이 헤맨 며칠.


이러다간 답답해서 웹 프로그래밍 공부할 기세...

(아니..먹고 살려면 당연히 해야!!!)



* 위의 내용을 작성하는데에는 머드초보님, 붉은기사님, Peleus Uhley 의 작성글을 참고하였습니다.


머드초보님의 블로그 하단에는, 각 언어로 Policy Server 를 구축하는 링크도 있습니다.

정말 유용한 내용 :) -> http://code.google.com/p/assql/wiki/SecurityInformation


머드초보님 블로그 : http://mudchobo.tistory.com/504

붉은기사님 블로그 : http://blog.naver.com/PostView.nhn?blogId=redknight2&logNo=68356555

Peleus Uhley : http://www.adobe.com/devnet/flashplayer/articles/socket_policy_files.html





/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


출처: https://code.google.com/p/assql/wiki/SecurityInformation


# Some basic security information.

As of Flash Player 9.0.124.0, Sockets are not allowed to make requests to ports on the same, or other domains, unless the domain you are connecting to is serving a socket policy file. Prior to 9.0.124.0, a crossdomain.xml file would work just fine. Now, however, you need to setup a server socket on port 843, that listens for socket connections from flash, and serves a socket policy file.

Here is the absolute simplest configuration for the socket policy file:

<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
   
<allow-access-from domain="*" to-ports="3306" />
</cross-domain-policy>

The policy file needs to be served from a socket, listening on port 843 (TCP). Flash will send the request "

<policy-file-request>
</policy-file-request>
\0", when the server receives this string, it should return the policy file, followed by a null byte.


Java Policy File Server:

See JavaPolicyFileServer wiki entry.


PHP Flash Policy Daemon:

http://ammonlauritzen.com/blog/2008/04/22/flash-policy-service-daemon/


C# Flash Policy Server:

http://giantflyingsaucer.com/blog/?p=15


VB.NET Flash Policy Server:

http://www.gamedev.net/community/forums/topic.asp?topic_id=455949


Python / Perl Flash Policy Servers:

http://www.adobe.com/devnet/flashplayer/articles/socket_policy_files.html


More Information:

http://www.adobe.com/devnet/flashplayer/articles/fplayer9_security_04.html

Comment by julian.r...@gmail.comAug 9, 2008

nice adobe. you Need root server rights to install this on your server. or somebody got a different solution?

Comment by Freima...@gmail.comAug 19, 2008

Has anyone seen a solution that works with python 2.4?

Comment by alexben...@gmail.comDec 10, 2008
Comment by ejf...@gmail.comAug 4, 2009

Has anyone tried setting up a Flash Policy Server using Amazon's EC2 service.

Comment by nimn...@gmail.comAug 20, 2009

My only concern about this wonderful library is that I'm writing my username and password to connect to the database inside my AIR application... how secure is this? how well protected is the source? I know this is definetly a HUGE RISK for Flex applications as anyone can decode the SWF file... but how secure is in AIR?

Comment by mich...@goldrush.giJan 20, 2010

@nimnrod Get the information through a webservice call or something with the first initial run and save it in the build in SQLite db, so in that way username/passwords are not hardcoded and you can change those settings every now and then and let the app check if there are new settings yes or no through the webservice (or whatever datasource you want to use).

Comment by realbudh...@gmail.comJul 19, 2010

And what will stop the user who decode the swf to do the same? The AS is executed on the users machine ... one or other way the information about the login is on the users machine. So he can see it. Maybe the basic user will not be able to ... but the bad guys are not basic users :)

Comment by davidjmc...@gmail.comOct 27, 2010

For security I use Zend AMF to put some layer of protection between client and db. Can anyone provide a use case for this lib instead of remoting? I am genuinely curious.


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



퍼온곳 : http://blog.naver.com/bon0110

 

 

플래시 XMLSocket crossdomain.xml 보안정책 문제점...해결....

 

미치는줄알았따... 결국 내가 해결한건 아니지만...팀장님꼐서.. 완료하셨따....

 

혹시나.. 후에 쓸일이나... 혹시나 누가 봣을때를 위해... 남겨놔야겠따...

 

다른글들 모두 맞다.. 다 대입하자...

 

(플래시9.0.124, 액션스크립트2.0, 자바 jdk1.5)

 

========================================

플래시9.0.124 구문 상단에

 

Security.allowDomain("도메인");
Security.loadPolicyFile("xmlsocket://도메인:포트");

 

넣어줘야한다. 843포트로 해야된다는데.. 우린 이상하게 다른 포트를 사용해도됐따...

 

결국 843 포트는 무용지물?... 어떻게하든 보안정책만 들어가면되는거다...

 

나머지 소켓 커넥트부분이나 sendData , onData는 레퍼런스를 따라썼다...

=========================================

crossdomain.xml 이다...

 

<?xml version=Ƈ.0' encoding='UTF-8'?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">

<cross-domain-policy>
    <site-control permitted-cross-domain-policies="master-only"/>
    <allow-access-from domain='도메인' to-ports="포트"/>
</cross-domain-policy>

 

여기에서 도메인과 포트엔 * 값을 주어도 된다고한다.

 

허나 우린 우리의 도메인과 포트는 소켓연결시의 포트이다.. (loadpolicyFile 포트가 아니다..)

 

그리고 xml 내부에 어떠한 옵션을 더 추가시켜주어도 상관없다... 무엇이든 정답인것이다.

 

** 포트는 총 두개인것이다.. loadpolicyFile  포트와 소켓연결시 포트

=========================================

자바소스...

ServerSocket ss;
  try
  {
   ss = new ServerSocket(PORT);
   System.out.println("클라이언트 "+ss+"접속 대기중");
   while(true)
   {
    Socket c= ss.accept();
    System.out.println("클라이언트 접속 : "+c);
    ThreadServers cs = new ThreadServers(c, ss+"", at);

    //이 구문은 의심치 말라.. 자체적 코딩으로 인해 생성자에 값을 더 넣어준것뿐이다.


    String returnText = "<?xml version=Ƈ.0'encoding='UTF-8' ?>"+
    "<!DOCTYPE cross-domain-policy SYSTEM \"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd\">"+
          "<cross-domain-policy>"+
          "<site-control permitted-cross-domain-policies=\"master-only\"/>"+
          "<allow-access-from domain=\"도메인\" to-ports=\"포트\"/>"+
          "</cross-domain-policy> ";


    cs.sendMessage(returnText);
    cs.start();
   }
  }catch(Exception e)
  {
   System.out.println(e.toString());
  }

 

이것이 관건이였따....!!!!!!!!!!!!!!!!!!!!!!!

ThreadServers 클래스 (만든것입니다. 그냥 서버코딩입니다.)

에서 클라이언트가 accept시 run을 하기전에

이 보안정책을 보내주어야한다!!! ㅡㅡ;;;;

 

나 항상 run()에다가 넣었따.. ㅡㅡ;;;;

 

아... 여기도 보안정책 xml옵션과 같이 어떠한 값을주어도상관없다... ㅡ,.ㅡ;;;;

 

ThreadServers의 run()에 넣지말고, (자신의 서버 run()메소드)

accept하자마자... 보안정책구문을 돌려주어야하는 것이었다..

젠장할....

 

그리고 서버를 마지막에 start()를 시키는 것이다...

 

sendMesage 메소드에서..

public synchronized void sendMessage(String str)

{
  out.write(str+"\0");
  out.flush();
 }
마지막에 \0 을 포함하였다.. 그냥 보안정책구문에서.. 보내주어도되지만..

만약을 생각해.. 최후에 넣었다는 것을 확인하기 위해서...

 

아...빼먹을뻔했다...

run()이되면 그 안에도 보안정책을 넣어줫따...

while((line=in.readLine()) != null)
   {
    System.out.println(line);
    if(line.trim().equals("<policy-file-request/>"))
    {
       String returnText = "<?xml version=Ƈ.0'encoding='UTF-8' ?>"+
     "<!DOCTYPE cross-domain-policy SYSTEM

          \"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd\">"+
           "<cross-domain-policy>"+
           "<site-control permitted-cross-domain-policies=\"master-only\"/>"+
           "<allow-access-from domain=\"도메인\" to-ports=\"포트\"/>"+
           "</cross-domain-policy> ";
     sendMessage(returnText);
    } 

혹시나 몰라서...일까? 아님 받고 주고 받고... 그거 때문인가... 하튼 한번 더 넣어준다..;;;

 

여기까지 읽은분들이 계실까...

혹 계셨는데.. 보안정책에 관한 문제가 해결이 않되셨다...

그러면..죄송합니다 꾸뻑 ㅡ,.ㅡ;;;


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


출처: http://holiclove.tistory.com/76



JavaPolicyFileServer  

# Sample Java Flash Policy File Server.

This is a simple Java servlet, that opens a server socket on port 843 when the web application is started. It listens for "

<policy-file-request>
</policy-file-request>

\0" requests, and writes the policy file to the connected client.

The policy file is read from "/tomcat/policyserver/ROOT/flashpolicy.xml", this can be changed in the servlet code.

Here is what you will need in web.xml:

<servlet> 
        <servlet-name>PolicyServerServlet</servlet-name> 
        <servlet-class>com.maclema.flash.PolicyServerServlet</servlet-class> 
        <load-on-startup>1</load-on-startup> 
</servlet> 
 
<servlet-mapping> 
        <servlet-name>PolicyServerServlet</servlet-name> 
        <url-pattern>/policyserver</url-pattern> 
</servlet-mapping>

and here is the servlet code:

package com.maclema.flash; 
 
import java.io.BufferedReader; 
import java.io.File; 
import java.io.FileReader; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.net.ServerSocket; 
import java.net.Socket; 
 
import javax.servlet.http.HttpServlet; 
 
public class PolicyServerServlet extends HttpServlet { 
        private static final long serialVersionUID = 1L; 
         
        private static ServerSocket serverSock; 
        private static boolean listening = true; 
        private static Thread serverThread; 
         
        static { 
                try { 
                        serverThread = new Thread(new Runnable(){ 
                                public void run() { 
                                        try { 
                                                System.out.println("PolicyServerServlet: Starting..."); 
                                                serverSock = new ServerSocket(843, 50); 
                                                 
                                                while ( listening ) { 
                                                        System.out.println("PolicyServerServlet: Listening..."); 
                                                        final Socket sock = serverSock.accept(); 
                                                         
                                                        Thread t = new Thread(new Runnable() { 
                                                                public void run() { 
                                                                        try { 
                                                                                System.out.println("PolicyServerServlet: Handling Request..."); 
                                                                                 
                                                                                sock.setSoTimeout(10000); 
                                                                                 
                                                                                InputStream in = sock.getInputStream(); 
                                                                                 
                                                                                byte[] buffer = new byte[23]; 
                                                                                 
                                                                                if ( in.read(buffer) != -1 && (new String(buffer)).startsWith("<policy-file-request/>") ) { 
                                                                                        System.out.println("PolicyServerServlet: Serving Policy File..."); 
                                                                                         
                                                                                        //get the local tomcat path, and the path to our flashpolicy.xml file 
                                                                                        File policyFile = new File("/tomcat/policyserver/ROOT/flashpolicy.xml"); 
                                                                                         
                                                                                        BufferedReader fin = new BufferedReader(new FileReader(policyFile)); 
                                                                                         
                                                                                        OutputStream out = sock.getOutputStream(); 
                                                                                         
                                                                                        String line; 
                                                                                        while ( (line=fin.readLine()) != null ) { 
                                                                                                out.write(line.getBytes()); 
                                                                                        } 
                                                                                         
                                                                                        fin.close(); 
                                                                                         
                                                                                        out.write(0x00); 
                                                                                         
                                                                                        out.flush(); 
                                                                                        out.close(); 
                                                                                } 
                                                                                else { 
                                                                                        System.out.println("PolicyServerServlet: Ignoring Invalid Request"); 
                                                                                        System.out.println("  " + (new String(buffer))); 
                                                                                } 
                                                                                 
                                                                        } 
                                                                        catch ( Exception ex ) { 
                                                                                System.out.println("PolicyServerServlet: Error: " + ex.toString()); 
                                                                        } 
                                                                        finally { 
                                                                                try { sock.close(); } catch ( Exception ex2 ) {} 
                                                                        } 
                                                                } 
                                                        }); 
                                                        t.start(); 
                                                } 
                                        } 
                                        catch ( Exception ex ) { 
                                                System.out.println("PolicyServerServlet: Error: " + ex.toString()); 
                                        } 
                                } 
                        }); 
                        serverThread.start(); 
                         
                } 
                catch ( Exception ex ) { 
                        System.out.println("PolicyServerServlet Error---"); 
                        ex.printStackTrace(System.out); 
                } 
        } 
         
        public void destroy() { 
                System.out.println("PolicyServerServlet: Shutting Down..."); 
                 
                if ( listening ) { 
                        listening = false; 
                } 
                 
                if ( !serverSock.isClosed() ) { 
                        try { serverSock.close(); } catch ( Exception ex ) {} 
                } 
        } 
}

and this is my flashpolicy.xml:

<?xml version="1.0"?> 
<!DOCTYPE cross-domain-policy SYSTEM "/xml/dtds/cross-domain-policy.dtd"> 
<cross-domain-policy> 
   <allow-access-from domain="*" to-ports="3306" /> 
</cross-domain-policy>


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


출처: http://airdev.tistory.com/247



Flash Player 9 Update 3(9,0,115,0) 이후부터는 소켓통신을 위해서 소켓 정책 파일을 필요로 합니다..

간단히 설명하자면..몇가지 보안 이슈들로 인해 플래시 플레이어는 이전 방식의 crossdomain.xml 대신 아래와 같은 소켓 정책 파일(이름은 상관없습니다..crossdomain.xml도 됩니다..)을 서버의 843포트를 통해 전달받아 1024이상의 포트에 접근합니다..

<cross-domain-policy>
    <site-control permitted-cross-domain-policies="master-only"/>
    <allow-access-from domain="*.apollocation.co.kr" to-ports="1280"/>
</cross-domain-policy>

[Flash Player 9의 보안 변경 사항 문서]
http://www.adobe.com/kr/devnet/flashplayer/articles/fplayer9_security.html

{해결 방법}
http://panzergruppe.hp.infoseek.co.jp/fspfd.html

위 사이트에서 제공하는 2개의 파일을 서버의 같은 폴더에 다운로드 받고 c 파일을 컴파일 하면 됩니다..

플래시(플렉스)에서는 Security.loadPolicyFile();를 호출할 필요없이 그냥 소켓을 연결하면 됩니다..

도움주신 막강 서버(+DB)개발자 장정철, 임지혁님께 감사드립니다..(_ _)
동근이도 땡큐^^

Good luck~ : )



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


출처: http://clack.tistory.com/m/post/view/id/319


crossdomain

플래시 플레이어 9.0.124 버전 이후부터는 crossdomain.xml 즉, 보안정책파일을 더이상 80포트로 접근할 수 없게 되었습니다.

따라서. Security.loadPolicyFile("http://domain.com/crossdomain.xml"); 로 선언된 보안정책은 적용되지 않습니다.


이를 해결하기위해선 http 프로토콜이 아닌, https 프로토콜을 이용하여 보안정책파일에 접근하시거나, 소켓접속시 843 포트로 보안정책파일을 전송해주어야 합니다.


https 를 이용한 접근방법은, 일반적인 https 구축방법에 따라 구축하신후 기존대로 사용하면 된다.


corossdomain.xml 샘플

<<?xml version="1.0"?>>

<<!-- http://www.adobe.com/crossdomain.xml -->>

<<cross-domain-policy>>

  <<allow-access-from domain="www.helpexamples.com" />>

  <<allow-access-from domain="*.adobe.com" />>

  <<allow-access-from domain="105.216.0.40" />>

<</cross-domain-policy>>



소켓통신 crossdomain

socket.connect(host, 80)을 호출하면 80 포트로 연결하기 전에 host의 843 포트로 연결합니다. 이 포트에는 socket master policy file을 반환하는 서버 애플리케이션이 리슨하고 있어야 합니다. 프로토콜은 다음과 같이 매우 간단합니다. 


플레시 플레이어 -> 정책 파일 서버(Policy File Server)

<policy-file-request/>


정책 파일 서버 -> 플레시 플레이어

<?xml version="1.0"?>

<cross-domain-policy>

    <site-control permitted-cross-domain-policies="master-only"/> 

    <allow-access-from domain="*.tabslab.com" to-ports="80" />

</cross-domain-policy> 


정책 파일 서버는 843 포트를 리슨하고 있다가 <policy-file-request/> 요청이 들어오면 정책 파일(XML)을 전송하고 소켓을 닫으면 됩니다.


SWF 파일이 소켓으로 연결하고자 하는 곳에 정책 파일 서버가 존재해야 하고, 정책이 tabslab.com 도메인에서 배포된 SWF에 대해서 80 포트만 접속을 허락하니 그 외의 모든 연결은 보안상 오류로 취급됩니다. 따라서 정책 파일 서버가 없거나 정책 파일 서버가 허락하지 않는 from 도메인과 포트로의 접근은 플레시 플레이어 자체가 제한해 버립니다. 아무곳으로의 통신을 막아 보안성을 높이게 되는거죠.


원래의 목적인 소켓 기반 HTTP 업로드를 위해 단계 별로 설명하자면...

(1) 도메인 내에서 업로드를 받는 서버의 방화벽에서 843 포트를 개방합니다. 

(2) 정책 파일 서버를 설치한 후 가동시킵니다. Telnet으로 연결 후 <policy-file-request/>를 전송해 올바른 응답을 하는지 테스트합니다.

(3) socket.connect(host, 80)로 연결 테스트합니다.


Security 클래스 메소드

Security.loadPolicyFile( "*" );   해당 플래시 파일에서 모든 ip주소에 대한 다른 서버에 있는 데이터를 로드할 수 있도록 허용할지 여부를 결정


Security.allowDomain( "*" );  크로스 무비 스크립팅, 다른 도메인의 SWF파일에 사용권한을 제공합니다. swf파일의 변수, 객체, 속성, 메서드 등을 검사 및 수정할 수 있도록 권한 부여



- allowDomain -


출처 : http://blog.naver.com/PostView.nhn?blogId=ddula97&logNo=30110468470&viewDate=&currentPage=1&listtype=0

   http://livedocs.adobe.com/flash/9.0_kr/ActionScriptLangRefV3/flash/system/Security.html#allowDomain()



이외에 플래시 플레이어 보안에 관한 내용은 아래 주소에 자세히 나와있다.

http://livedocs.adobe.com/flash/9.0_kr/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00000347.html


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

반응형