>  기사  >  운영 및 유지보수  >  Java 애플리케이션의 보안 샌드박스 메커니즘은 무엇입니까?

Java 애플리케이션의 보안 샌드박스 메커니즘은 무엇입니까?

PHPz
PHPz앞으로
2023-05-16 18:26:22902검색

소스코드를 자주 읽어보면 자바 소스코드에 다음과 비슷한 코드가 있다는 것을 알 수 있습니다.

<code class="hljs java">class File {<br>  // 判断一个磁盘文件是否存在<br>  public boolean exists() {<br>    SecurityManager security = System.getSecurityManager();<br>    if (security != null) {<br>      security.checkRead(path);<br>    }<br>    ...<br>  }<br>}<br></code>


이것은 당연히 접근권한이 있는지 확인하는 보안체크 코드입니다. 디스크 경로. Java 언어에는 어떤 종류의 보안 검사 코드가 필요한가요? 클라이언트 소켓의 연결 기능 소스 코드를 살펴보겠습니다. 사용자가 특정 네트워크 주소에 연결할 수 있는 권한이 있는지 확인해야 합니다.

<code class="hljs cs">class Socket {<br>  public void connect(SocketAddress endpoint, int timeout) {<br>    ...<br>    SecurityManager security = System.getSecurityManager();<br>    if (security != null) {<br>       if (epoint.isUnresolved())<br>          security.checkConnect(epoint.getHostName(), port);<br>       else<br>          security.checkConnect(addr.getHostAddress(), port);<br>       }<br>    }<br>    ...<br>  }<br>}<br></code>


서버 소켓의 소스 코드를 보면, 포트의 수신 권한

<code class="hljs cs">class ServerSocket {<br>  public void bind(SocketAddress endpoint, int backlog) {<br>    ...<br>    SecurityManager security = System.getSecurityManager();<br>    if (security != null)<br>       security.checkListen(epoint.getPort());<br>    ...<br>  }<br>}<br></code>


IO 작업과 관련된 모든 메서드 호출에는 보안 검사가 필요한 것 같습니다. IO 작업과 관련된 권한 확인은 이해할 수 있는 것으로 보이며, 사용자 프로세스는 모든 IO 리소스에 마음대로 액세스할 수 없습니다. 그런데 환경변수도 마음대로 읽을 수 없고, 모든 환경변수가 아니라 특정 환경변수만 제한하는 것이 좀 무리한 것 아닌가?

<code class="hljs cs">class System {<br>  public static String getenv(String name) {<br>    SecurityManager sm = getSecurityManager();<br>    if (sm != null) {<br>       sm.checkPermission(new RuntimePermission("getenv."+name));<br>    }<br>    return ProcessEnvironment.getenv(name);<br>  }<br>}<br></code>


자바의 보안 검사 관리자와 운영체제의 권한 검사는 동일한 개념이 아니기 때문입니다. 자바는 서버 측 애플리케이션뿐만 아니라 브라우저(애플릿)에서도 클라이언트로 실행할 수 있습니다. JVM은 앱 형태의 휴대폰(J2ME)에서 다양한 플랫폼에 대해 다양한 보안 전략을 사용합니다. 일반적으로 애플릿에 대한 제한은 매우 엄격하며 일반적으로 애플릿은 로컬 파일을 작동하는 것이 허용되지 않습니다. 특정 IO 작업을 수행하기 전에 Java의 보안 검사를 통과하면 운영 체제는 계속해서 권한 검사를 수행합니다.

Java 프로그램을 로컬에서 실행할 때는 일반적으로 보안 검사기를 기본적으로 열지 않습니다. 이를 열려면 jvm 매개변수를 실행해야 합니다.

<code class="hljs shell">$ java -Djava.security.manager xxx<br>$ java -Djava.security.manager -DDjava.security.policy="${policypath}"<br></code>


보안 제한을 사용자 정의할 수 있으므로 특정 보안 정책 파일도 제공해야 합니다. 기본적으로 정책 파일 경로는 JAVA_HOME/jre/lib/security/java.policy입니다. 이 파일에 작성된 내용을 살펴보겠습니다.

<code class="hljs dart">// 内置扩展库授权规则<br>// 表示 JAVA_HOME/jre/lib/ext/ 目录下的类库可以全权访问任意资源<br>// 包含 javax.swing.*, javax.xml.*, javax.crypto.* 等等<br>grant codeBase "file:${{java.ext.dirs}}/*" {<br> permission java.security.AllPermission;<br>};<br><br>// 其它类库授权规则<br>grant {<br> // 允许线程调用自己的 stop 方法自杀<br> permission java.lang.RuntimePermission "stopThread";<br> // 允许程序监听 localhost 的随机可用端口,不允许随意订制端口<br> permission java.net.SocketPermission "localhost:0", "listen";<br> // 限制获取系统属性,下面一系列的配置都是只允许读部分内置属性<br> permission java.util.PropertyPermission "java.version", "read";<br> permission java.util.PropertyPermission "java.vendor", "read";<br> permission java.util.PropertyPermission "java.vendor.url", "read";<br> permission java.util.PropertyPermission "java.class.version", "read";<br> permission java.util.PropertyPermission "os.name", "read";<br> permission java.util.PropertyPermission "os.version", "read";<br> permission java.util.PropertyPermission "os.arch", "read";<br> permission java.util.PropertyPermission "file.separator", "read";<br> permission java.util.PropertyPermission "path.separator", "read";<br> permission java.util.PropertyPermission "line.separator", "read";<br> permission java.util.PropertyPermission "java.specification.version", "read";<br> permission java.util.PropertyPermission "java.specification.vendor", "read";<br> permission java.util.PropertyPermission "java.specification.name", "read";<br> permission java.util.PropertyPermission "java.vm.specification.version", "read";<br> permission java.util.PropertyPermission "java.vm.specification.vendor", "read";<br> permission java.util.PropertyPermission "java.vm.specification.name", "read";<br> permission java.util.PropertyPermission "java.vm.version", "read";<br> permission java.util.PropertyPermission "java.vm.vendor", "read";<br> permission java.util.PropertyPermission "java.vm.name", "read";<br>};<br></code>


grant codeBase 매개 변수가 제공되면 권한이 구성됩니다. 특정 클래스 라이브러리. codeBase가 지정되지 않은 경우 규칙은 다른 모든 라이브러리에 대해 구성된 규칙입니다.

보안 검사에 실패하면 java.security.AccessControlException 예외가 발생합니다. 보안 검사를 통과하더라도 운영 체제의 권한 검사가 실패할 수 있으며, 이 경우 다른 유형의 예외가 발생합니다.

위에서 구성한 규칙을 따르면 기본 보안 정책을 사용하는 JVM은 권한 부여 규칙이 화이트리스트를 사용하므로 로컬 파일에 액세스할 수 없습니다. 로컬 파일에 액세스해야 하는 경우 다음 규칙을 추가할 수 있습니다

<code class="hljs lua">permission java.io.FilePermission "/etc/passwd", "read";<br>permission java.io.FilePermission "/etc/shadow", "read,write";<br>permission java.io.FilePermission "/xyz", "read,write,delete";<br>// 允许读所有文件<br>permission java.io.FilePermission "*", "read";<br></code>


권한 구성 매개변수는 생성자 매개변수와 정확히 일치합니다

<code class="hljs java">public FilePermission(String path, String actions) {<br>  super(path);<br>  init(getMask(actions));<br>}<br></code>


Java 기본 보안 규칙은 여러 주요 모듈로 나누어지며, 각 모듈에는 자체 구성 매개변수가 있습니다

Java 애플리케이션의 보안 샌드박스 메커니즘은 무엇입니까?

여기서 AllPermission은 모든 권한을 여는 것을 의미합니다. 내장된 권한 모듈이 아닌 초대되지 않은 게스트인 HibernatePermission도 있습니다. 이는 Hibernate 프레임워크에 의해 사용자 정의되며 이는 보안 규칙이 사용자 정의 확장을 지원한다는 것을 의미합니다. 확장하는 것은 쉽습니다. Permission 하위 클래스를 작성하고 해당 클래스의 네 가지 추상 메서드를 구현하면 됩니다.

<code class="hljs java">abstract class Permission {<br>  // 权限名称,对于文件来说就是文件名,对于套接字来说就是套接字地址<br>  // 它的意义是子类可定制的<br>  private String name;<br>  // 当前权限对象是否隐含了 other 权限<br>  // 比如 AllPermission 的这个方法总是返回 true<br>  public abstract boolean implies(Permission other);<br>  // equals 和 hashcode 用于权限比较<br>  public abstract boolean equals(Object obj);<br>  public abstract int hashCode();<br>  // 权限选项 read,write,xxx<br>  public abstract String getActions();<br>}<br><br>class CustomPermission extends Permission {<br>  private String actions;<br>  CustomPermission(string name, string actions) {<br>    super(name)<br>    this.actions = actions;<br>  }<br>  ...<br>}<br></code>


JVM이 시작되면 프로필에 정의된 권한 규칙이 권한 풀에 로드됩니다. 사용자 프로그램은 특정 API 메서드의 권한 풀을 사용하여 이 API를 호출할 수 있는 권한이 포함되어 있는지 확인합니다. 결국 호출 권한 풀에 구현될 것입니다. 각 권한 개체의 암시적 메서드는 지정된 권한이 있는지 확인하는 데 사용됩니다.

<code class="hljs cs">class CustomAPI {<br>  public void someMethod() {<br>    SecurityManager sec = System.getSecurityManager();<br>    if(sec != null) {<br>      sec.CheckPermission(new CustomPermission("xname", "xactions"));<br>    }<br>    ...<br>  }<br>}<br></code>


보안 확인을 활성화하면 프로그램의 실행 효율성이 떨어지게 됩니다. 프로필에 정의된 권한 규칙이 너무 많으면 확인 효율성이 매우 느려지므로, 보안 확인에 주의하여 아껴서 사용하시기 바랍니다. .

샌드박스에는 많은 보안 체크포인트가 있습니다. 아래에는 몇 가지 일반적인 시나리오가 나와 있습니다.

  1. 파일 작업

  2. 소켓 작업

  3. 스레드 및 스레드 그룹

  4. 클래스 로더 제어

  5. 반사 제어

  6. 스레드 스택 정보 획득

  7. 네트워크 프록시 제어

  8. 쿠키 읽기 및 쓰기 제어

서버 프로그램에 보안 검사가 켜져 있는 경우 정책 구성에서 많은 보안 검사를 열어야 합니다. 파일 보안 설정은 매우 번거롭고 구성이 너무 많으면 검사 성능에도 일정한 손실이 발생합니다. 이는 Android 애플리케이션 권한 설정과 다소 유사합니다. 일련의 애플리케이션 하위 권한이 각 Android 애플리케이션의 구성 파일에 나열되어야 합니다. 그러나 Java로 서버측 프로그램을 작성할 때 보안 검사를 켤 필요는 없는 것 같습니다.

위 내용은 Java 애플리케이션의 보안 샌드박스 메커니즘은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제