Java 安全 | SecurityManager

admin 2025年6月7日23:44:33评论19 views字数 16677阅读55分35秒阅读模式

SecurityManager

前言

对于 SecurityManager 来说, 在读底层源码时经常会遇到它, 但从没仔细研究它是用来干嘛的, 以及之前在 RMI 学习时也曾主动配置过 SecurityManager. 本着读源码就读个痛快的缘故因此在此折腾一下 SecurityManager.

简介

SecurityManager 是 Java内置的一种安全机制, 默认处于禁用状态.

其在 JDK 17 中将其移除了, 具体可以参考 JEP 411: https://openjdk.org/jeps/411 以及 JEP 486: https://openjdk.org/jeps/486

但由于 Java 项目大多数会遇到 JDK 17 以下版本的项目, 所以在这里有必要对其进行一个研究.

初识

我们可以打开java.io.File类中查看它的一些相关方法, 可以发现大多数都使用了SecurityManager进行校验, 代码案例图如下:

Java 安全 | SecurityManager

在其中我们可以看到的是, 底层函数使用System.getSecurityManger()进行得到一个SecurityManager, 随后调用它的方法进行一系列验证, 而有趣的是它经常判断if(security != null), 那么什么时候SecurityManagerNULL, 什么时候不为NULL, 它又是从何而来的?

Launcher

在之前研究ClassLoader中我们是通过引入sun.misc.Launcher类来进行观察AppClassLoader, ExtClassLoader, AppClassLoader进行研究的, 而在这边我们依然重新找到它, 并且进行观察它的源码设计如下:

Java 安全 | SecurityManager

上述折叠部分是ClassLoader的初始化逻辑, 而使用绿框圈出来的是SecurityManager的初始化逻辑, 在这里提前说明一点: System.getProperty读取-D参数的值, 例如: java -D参数KEY=参数VALUE 类名, 以下是一个具体的案例:

Java 安全 | SecurityManager

设置与获取 SecurityManager

那么通过该案例与Launcher类结合起来看即可知道, 一个SecurityManager想要使用可以使用如下两点:

  • 增加 -Djava.security.manager 参数或 -Djava.security.manager=default 采用系统默认的
  • 增加 -Djava.security.manager=类名 来加载自定义的 SecurityManager

而 SecurityManager 的初始阶段由System.setSecurityManager(以上两种情况)来进行设置到系统中的, 随后在我们调用自己的类中的 main 方法时即可通过System.getSecurityManager()来进行获取, 以下是这几种方式的设置案例.

  1. 没有任何参数的情况

    Java 安全 | SecurityManager
  2. 指明了 -Djava.security.manager[=default] 情况

    Java 安全 | SecurityManager
  3. 指明了 -Djava.security.manager=自定义SecurityManager 情况

    Java 安全 | SecurityManager

当然也可以通过SecurityManager.setSecurityManager进行设置自己想要的SecurityManager. 因为无论是否带参数了, 最终都会调用SecurityManager.setSecurityManager.

policy 配置文件

当运行未知的Java程序的时候,该程序可能有恶意代码(删除系统文件、重启系统等),为了防止运行恶意代码对系统产生影响,需要对运行的代码的权限进行控制,这时候就要启用Java安全管理器。而通常默认的 安全管理器配置文件 为jdk8u131jrelibsecurityjava.security & jdk8u131jrelibsecurityjava.policy, 如图:

Java 安全 | SecurityManager

首先我们看一下java.security配置文件的内容 (删除注释后的), 如下:

securerandom.strongAlgorithms=Windows-PRNG:SunMSCAPI,SHA1PRNG:SUN

login.configuration.provider=sun.security.provider.ConfigFile

policy.provider=sun.security.provider.PolicyFile

policy.url.1=file:${java.home}/lib/security/java.policy
policy.url.2=file:${user.home}/.java.policy

policy.expandProperties=true

policy.allowSystemProperty=true

policy.ignoreIdentityScope=false

keystore.type=jks

keystore.type.compat=true

package.access=sun.,com.sun.xml.internal.,com.sun.imageio.,com.sun.istack.internal.,com.sun.jmx.,com.sun.media.sound.,com.sun.naming.internal.,com.sun.proxy.,com.sun.corba.se.,com.sun.org.apache.bcel.internal.,com.sun.org.apache.regexp.internal.,com.sun.org.apache.xerces.internal.,com.sun.org.apache.xpath.internal.,com.sun.org.apache.xalan.internal.extensions.,com.sun.org.apache.xalan.internal.lib.,com.sun.org.apache.xalan.internal.res.,com.sun.org.apache.xalan.internal.templates.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.apache.xalan.internal.xslt.,com.sun.org.apache.xalan.internal.xsltc.cmdline.,com.sun.org.apache.xalan.internal.xsltc.compiler.,com.sun.org.apache.xalan.internal.xsltc.trax.,com.sun.org.apache.xalan.internal.xsltc.util.,com.sun.org.apache.xml.internal.res.,com.sun.org.apache.xml.internal.security.,com.sun.org.apache.xml.internal.serializer.utils.,com.sun.org.apache.xml.internal.utils.,com.sun.org.glassfish.,com.oracle.xmlns.internal.,com.oracle.webservices.internal.,oracle.jrockit.jfr.,org.jcp.xml.dsig.internal.,jdk.internal.,jdk.nashorn.internal.,jdk.nashorn.tools.,com.sun.activation.registries.,com.sun.java.accessibility.,com.sun.browser.,com.sun.glass.,com.sun.javafx.,com.sun.media.,com.sun.openpisces.,com.sun.prism.,com.sun.scenario.,com.sun.t2k.,com.sun.pisces.,com.sun.webkit.,jdk.management.resource.internal.

package.definition=sun.,com.sun.xml.internal.,com.sun.imageio.,com.sun.istack.internal.,com.sun.jmx.,com.sun.media.sound.,com.sun.naming.internal.,com.sun.proxy.,com.sun.corba.se.,com.sun.org.apache.bcel.internal.,com.sun.org.apache.regexp.internal.,com.sun.org.apache.xerces.internal.,com.sun.org.apache.xpath.internal.,com.sun.org.apache.xalan.internal.extensions.,com.sun.org.apache.xalan.internal.lib.,com.sun.org.apache.xalan.internal.res.,com.sun.org.apache.xalan.internal.templates.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.apache.xalan.internal.xslt.,com.sun.org.apache.xalan.internal.xsltc.cmdline.,com.sun.org.apache.xalan.internal.xsltc.compiler.,com.sun.org.apache.xalan.internal.xsltc.trax.,com.sun.org.apache.xalan.internal.xsltc.util.,com.sun.org.apache.xml.internal.res.,com.sun.org.apache.xml.internal.security.,com.sun.org.apache.xml.internal.serializer.utils.,com.sun.org.apache.xml.internal.utils.,com.sun.org.glassfish.,com.oracle.xmlns.internal.,com.oracle.webservices.internal.,oracle.jrockit.jfr.,org.jcp.xml.dsig.internal.,jdk.internal.,jdk.nashorn.internal.,jdk.nashorn.tools.,com.sun.activation.registries.,com.sun.java.accessibility.,com.sun.browser.,com.sun.glass.,com.sun.javafx.,com.sun.media.,com.sun.openpisces.,com.sun.prism.,com.sun.scenario.,com.sun.t2k.,com.sun.pisces.,com.sun.webkit.,jdk.management.resource.internal.

security.overridePropertiesFile=true

ssl.KeyManagerFactory.algorithm=SunX509
ssl.TrustManagerFactory.algorithm=PKIX

networkaddress.cache.negative.ttl=10

krb5.kdc.bad.policy=tryLast

jdk.certpath.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224

jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024

jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768, EC keySize < 224

jdk.tls.legacyAlgorithms=K_NULL, C_NULL, M_NULL, DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_anon_EXPORT, DH_DSS_EXPORT, DH_RSA_EXPORT, RSA_EXPORT, DH_anon, ECDH_anon, RC4_128, RC4_40, DES_CBC, DES40_CBC, 3DES_EDE_CBC

jdk.xml.dsig.secureValidationPolicy=disallowAlg http://www.w3.org/TR/1999/REC-xslt-19991116,disallowAlg http://www.w3.org/2001/04/xmldsig-more#rsa-md5,disallowAlg http://www.w3.org/2001/04/xmldsig-more#hmac-md5,disallowAlg http://www.w3.org/2001/04/xmldsig-more#md5,maxTransforms 5,maxReferences 30,disallowReferenceUriSchemes file http https,minKeySize RSA 1024,minKeySize DSA 1024,noDuplicateIds,noRetrievalMethodLoops

其中我们可以看到定义的policy.url.1中指明了file:${java.home}/lib/security/java.policy文件, 而该文件的内容如下:

// Standard extensions get all permissions by default

grant codeBase "file:${{java.ext.dirs}}/*" {
        permission java.security.AllPermission;
};

// default permissions granted to all domains

grant {
        // Allows any thread to stop itself using the java.lang.Thread.stop()
        // method that takes no argument.
        // Note that this permission is granted by default only to remain
        // backwards compatible.
        // It is strongly recommended that you either remove this permission
        // from this policy file or further restrict it to code sources
        // that you specify, because Thread.stop() is potentially unsafe.
        // See the API specification of java.lang.Thread.stop() for more
        // information.
        permission java.lang.RuntimePermission "stopThread";

        // allows anyone to listen on dynamic ports
        permission java.net.SocketPermission "localhost:0", "listen";

        // "standard" properies that can be read by anyone

        permission java.util.PropertyPermission "java.version", "read";
        permission java.util.PropertyPermission "java.vendor", "read";
        permission java.util.PropertyPermission "java.vendor.url", "read";
        permission java.util.PropertyPermission "java.class.version", "read";
        permission java.util.PropertyPermission "os.name", "read";
        permission java.util.PropertyPermission "os.version", "read";
        permission java.util.PropertyPermission "os.arch", "read";
        permission java.util.PropertyPermission "file.separator", "read";
        permission java.util.PropertyPermission "path.separator", "read";
        permission java.util.PropertyPermission "line.separator", "read";

        permission java.util.PropertyPermission "java.specification.version", "read";
        permission java.util.PropertyPermission "java.specification.vendor", "read";
        permission java.util.PropertyPermission "java.specification.name", "read";

        permission java.util.PropertyPermission "java.vm.specification.version", "read";
        permission java.util.PropertyPermission "java.vm.specification.vendor", "read";
        permission java.util.PropertyPermission "java.vm.specification.name", "read";
        permission java.util.PropertyPermission "java.vm.version", "read";
        permission java.util.PropertyPermission "java.vm.vendor", "read";
        permission java.util.PropertyPermission "java.vm.name", "read";
};

该文件具体是做什么的后面我们会进行说明, 那么我们不禁思考一个问题, 它们是从哪里加载进来的?

底层处理逻辑

Security 类【policy 文件查找规则】

java.security.Security类中, 定位到它的initialize方法, 我们可以看到对java.security文件的初始化读取工作:

Java 安全 | SecurityManager

所以Security这个类我们暂时可以理解为基于java.security文件Properties工具类, 我们可以创建如下代码进行验证说法:

Java 安全 | SecurityManager

java.security文件的读取我们已经知道被哪个核心类使用了, 接下来我们要看的是java.policy文件是在哪里被使用了, 其中就会涉及到我们案例中举例的policy.provider这个配置项的值.

ORBUtility 类【policy解析逻辑】

com.sun.corba.se.impl.orbutil.ORBUtility这个类从哪里进行初始化的, 我们并不关心, 我们只需要知道从哪里使用了policy.provider配置项的值即可, 在它的getClassSecurityInfo方法中, 如图:

Java 安全 | SecurityManager
sun.security.provider.PolicyFile 类【自定义 policy & 系统默认 policy】

实际上这里通过反射将sun.security.provider.PolicyFile通过反射进行初始化了, 我们可以编写如下测试代码进行模拟调用Policy.getPolicy()方法并查看它的返回结果, 不出意外的话会返回一个sun.security.provider.PolicyFile对象:

Policy policy = Policy.getPolicy();
System.out.println(policy); // sun.security.provider.PolicyFile@74a14482

那么我们接着看一下该类的初始化代码做了一些什么事情:

Java 安全 | SecurityManager

其具体的解析逻辑不是我们关注的, 从中我们可以看到的是, 如果指明了-Djava.security.policy文件, 那么则会调用PolicyFile.init方法进行读取. 那如果没有指明-Djava.security.policy参数, 实际上initPolicyFile方法中也有它的另一个分支, 如图:

Java 安全 | SecurityManager

这里我们可以看到默认的加载逻辑了, 没有传递-Djava.security.policy=配置文件时, 则会调用到默认的file:${java.home}/lib/security/java.policy & file:${user.home}/.java.policy.

所以通常如果我们想要使用系统默认的SecurityManager则无需指明-Djava.security.policy=配置文件, 而如果我们想要自定义配置文件时, 我们需要指明该参数.

正常使用方法

简单 Demo

我们先使用一个简单的案例进行演示, 首先是没有开启SecurityManager的案例, 如下:

package com.heihu577;

publicclassMain{
publicstaticvoidmain(String[] args){
        System.out.println("当前 JDK 版本: " + System.getProperty("java.version"));
        System.setProperty("java.version""你猜~");
        System.out.println("修改后的 JDK 版本: " + System.getProperty("java.version"));
/*
         当前 JDK 版本: 1.8.0_131
   修改后的 JDK 版本: 你猜~
        */

    }
}

在没有SecurityManager参与的情况下, 我们成功修改了java.version. 那么如果我们引入SecurityManager之后呢?

Java 安全 | SecurityManager

直接抛出了异常. 后面我们会慢慢的揭开这其中的奥秘.

policy 配置文件结构说明

我们看一下默认的file:${java.home}/lib/security/java.policy文件结构是怎么样的:

Java 安全 | SecurityManager

而给出对应的关键字解释如下:

  • grant: 用于声明一个权限授予块,定义一组代码需要被赋予的权限。

  • codeBase "值": 指定受权限控制的代码来源(位置)。其中"值"的部分可以是:

    目录/ -> 表示目录下所有 .class 文件, 不包括 .jar 文件.

    目录/* -> 表示目录下所有 .class 文件以及 .jar 文件.

    目录/- -> 表示目录下所有 .class 文件以及 .jar 文件, 包括子目录.

    "值"的部分也可以通过 ${} 来进行引用系统属性.

  • permission:

    java.security.AllPermission表示允许所有权限.

    java.util.PropertyPermission表示键值对Permission.

    java.lang.RuntimePermission表示Runtime使用的Permission.

    ... (后面会对这些 Permission 详细解释)

当然对于文件结构也可以参考官方文档: https://docs.oracle.com/javase/8/docs/technotes/guides/security/PolicyFiles.html

这里的配置原则如下:

  • 没有配置的权限表示没有。
  • 只能配置有什么权限,不能配置禁止做什么。
  • 同一种权限可多次配置,取并集。
  • 统一资源的多种权限可用逗号分割。
配置文件中 grant & codeBase 小实验

如果不做实验, 只是丢一些概念到上面, 那太模糊了, 接下来来做一个小实验, 在SecurityManager开启的情况下进行修改java.version系统变量的值, 我们在file:${java.home}/lib/security/java.policy增加如下声明:

Java 安全 | SecurityManager

这里指明了笔者DebuggerDemo编译并运行的路径, 最终由于permission java.security.AllPermission;的定义可以成功修改java.version的值.

Permission 说明【配置文件 & Java 类 都存在】

在上面给出的三个 Permission 中, 我们可以观察它的继承链:

Java 安全 | SecurityManager

可以发现无论如何变化, 它们都是实现了java.security.Permission这个类的, 而java.security.Permission这个类是一个以abstract关键字指明的抽象类.

而之所以之前在policy文件中看见很多Permission的参数不一致, 实际上在这里我们也能够找到原因:

Java 安全 | SecurityManager

这每个 Permission 定义, 都有不同的含义, Permission | BasicPermission这个抽象类有很多实现, 具体如下:

Java 安全 | SecurityManager

所以我们在阅读底层代码时会遇到各种各样不同的 Permission, 实际上它是在policy文件中的定义, 用来比对是否允许操作使用的.

再谈 SecurityManager

在之前初识中我们仅仅只是讲了SecurityManager如何进行设置, 以及设置下来与不设置的区别是什么, 现在我们重新认识以下SecurityManager, 我们要开始理解它的设计大致是用来干嘛的, 首先, SecurityManager中定义了如下方法:

Java 安全 | SecurityManager

在这个方法列表中, 我们可以看到几个经典的规律, hasAllPermission方法的定义以及大部分方法都是checkXXX打头.

hasAllPermission & checkXXX 定义

那么我们先来看一下hasAllPermission方法的定义:

Java 安全 | SecurityManager

而更加有趣的则是这些checkXXX方法以及hasAllPermission方法都调用了checkPermission方法进行调用, 如图:

Java 安全 | SecurityManager

核心都是调用checkPermission方法进行验证权限的, 不过我们先不着急研究checkPermission方法做了什么, 先来自定义一个SecurityManager, 目的其研究它的定位, 是用来干什么的, 随后再进行理解checkPermission方法做了什么.

自定义 SecurityManager【小 WAF 实现】

接下来我们可以实现一个自定义的 SecurityManager 了, 并且我们借用SecurityManager进行实现一个WAF, 禁止调用某方法, 首先我们可以看一下System.exit(0)方法的底层:

Java 安全 | SecurityManager

在之前, 我们的SecurityManager是用来判断当前的权限是否在policy配置文件中有定义来实现具体方法的权限判断的, 而如果我们自定义的SecurityManager这么写:

package com.heihu577;

publicclassMain{
publicstaticclassExitSecurityManagerextendsSecurityManager{
@Override
publicvoidcheckExit(int status){
thrownew SecurityException("禁止调用 System.exit() 方法");
        }
    }

publicstaticvoidmain(String[] args){
        System.setSecurityManager(new ExitSecurityManager());
        System.exit(0);
    }
}

那么就依赖于SecurityManager的机制, 巧妙的利用了SecurityManagercheckXXX方法在函数底层中的判断, 将System.exit()这个方法给 BAN 掉了, 如图:

Java 安全 | SecurityManager

访问控制器: AccessController【SecurityManager核心】

checkPermission 方法使用【判断某 Permission 是否在 policy 配置文件中定义】

话说回来, 我们继续研究以下checkPermission方法做了什么:

Java 安全 | SecurityManager

方法的定义很简单, 只是间接的调用了java.security.AccessController.checkPermission(传递过来的参数);, 所以重点是java.security.AccessController它做了一些什么事情, 我们没有开启SecurityManager, 可以观察如下结果:

Java 安全 | SecurityManager

如果java.policy中定义了permission java.security.AllPermission;, 那么java.security.AccessController.checkPermission(new AllPermission())会返回true.

那么如果没有定义则会抛出异常:

Java 安全 | SecurityManager

所以实际上java.security.AccessController.checkPermission方法是用来比对: 当前传入进来的Permission, 在java.policy (系统默认 or 自定义policy)文件中对应的grant (grant codeBase || grant)中是否存在定义, 如果不存在定义则会直接抛出异常. 如果存在定义则静默返回.

而 API 文档 (https://www.apiref.com/java8/java/security/AccessController.html#checkPermission-java.security.Permission-) 对它的介绍如下:

Java 安全 | SecurityManager
Permissions::implies 检查是否存在相应的权限

官方 API: https://www.apiref.com/java8/java/security/Permissions.html, 为什么这里突然提到该类, 实际上是因为checkPermission这个方法底层中使用了该类, 并且用它来进行鉴权, 这里简单看一下底层处理机制即可, 首先定义如下java.policy文件内容:

Java 安全 | SecurityManager

定义完毕后, 我们DebuggerDemo代码如下, 随后进行 Debug:

publicclassDebuggerDemo{
publicstaticvoidmain(String[] args){
        java.security.AccessController.checkPermission(new PropertyPermission("hack02""read"));
        System.out.println("代码成功走到该行~");
    }
}

如图:

Java 安全 | SecurityManager

对于AccessControlContext的底层处理过程我们不必细究, 只需要理解它们之间的对应关系即可, 最终会调用到ProtectionDomain::implies方法中进行权限查找, 过程如下:

Java 安全 | SecurityManager

可以看到的是, 我们的java.policy (默认 policy 文件)成功被解析, 并且马上通过Permissions::implies进行权限判断, 如图:

Java 安全 | SecurityManager

Permissions::implies在官方文档中的说明如下:

Java 安全 | SecurityManager

doPrivileged 方法使用【借用权限】

以下所有的代码案例测试, 都指明了 -Djava.security.manager, 也就是开启了 SecurityManager.

对于该方法的使用, 我们需要创建如下项目结构:

Java 安全 | SecurityManager
WriteFile01 模块测试【允许写操作】
定义 java.policy 权限

随后在java.policy (系统默认)文件中创建如下内容:

grant codeBase "file:///C:/Users/Administrator/Desktop/javaCode/SecurityManager02/WriteFile01/target/classes/" {
       permission  java.io.FilePermission "D:\test.txt", "write";
};

其目的则是只允许WriteFile01模块进行文件写操作, 不给予WriteFile02文件写操作. 为什么如上这么定义呢?在File::createNewFile方法中可以看到底层校验逻辑:

Java 安全 | SecurityManager

所以才定义的permission java.io.FilePermission "D:\test.txt", "write";.

测试写操作

好, 那么我们话说回来, 在WriteFile01模块中创建如下代码:

package com.heihu577;

import java.io.File;
import java.io.IOException;
import java.security.AccessController;
import java.security.PrivilegedAction;

publicclassFileUtils{
publicstaticvoidmain(String[] args)throws IOException {
new FileUtils().mkFile("D:\test.txt");
new FileUtils().mkFile2("D:\test.txt");
    }

publicvoidmkFile(String file)throws IOException {
new File(file).createNewFile();
    }

publicvoidmkFile2(String file){
        AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run(){
try {
new File(file).createNewFile();
                } catch (IOException e) {
thrownew RuntimeException(e);
                }
returnnull;
            }
        });
    }
}

在这里注意一下 mkFile 以及 mkFile2 方法体的定义, mkFile2 是使用了 AccessController.doPrivileged 允许让别的模块调用方法时借用其当前的权限.

其最终结果可以看到的是, 虽然开启了 SecurityManager, 但是由于java.policy中允许对D:\test.txt进行写操作, 所以最终可以操作成功:

Java 安全 | SecurityManager
WriteFile02 模块测试【不允许写操作】

由于我们的java.policy文件中没有定义WriteFile02Permission, 所以我们的WriteFile02模块是不允许写操作的.

在 pom.xml 中引入 WriteFile01

我们可以在WriteFile02中定义pom.xml, 引入WriteFile01, 结果如下:

<dependencies>
<dependency>
<groupId>com.heihu577</groupId>
<artifactId>WriteFile01</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
测试写操作【成功与失败案例】

定义如下代码:

package com.heihu577;

import java.io.IOException;

publicclassWriteFileDemo{
publicstaticvoidmain(String[] args)throws IOException {
        FileUtils fileUtils = new FileUtils();
        fileUtils.mkFile("D:\test.txt");
    }
}

最终运行结果:

Java 安全 | SecurityManager

最终写入失败!因为我们并没有在java.policy文件中定义WriteFile02模块允许任何操作.

但是我们可以利用WriteFile01模块所定义的mkFile2方法进行操作, 因为WriteFile01 模块的 FileUtils::mkFile2方法体中使用了AccessController.doPrivileged让别的模块借用其权限进行操作, 结果如下:

Java 安全 | SecurityManager

这就是AccessController.doPrivileged()方法的作用~

小总结

doPrivileged() 就像是:

  • 你(B 应用)去朋友家(A 应用)做客,朋友(A 应用)临时给你(B 应用)一把钥匙(权限),让你可以打开冰箱拿饮料(原本你没这权限)。
  • 但这把钥匙只能开冰箱,不能开保险柜,而且你离开朋友家后,钥匙就自动失效了。
  • 这样既保证了朋友家的安全,又让你能临时使用必要的资源。

Reference

SecurityManager 入门: https://www.cnblogs.com/yiwangzhibujian/p/6207212.html

SecurityManager 初识: https://blog.spoock.com/2019/12/21/Getting-Started-with-Java-SecurityManager-from-Zero/

SecurityManager 权限校验: https://blog.spoock.com/2019/12/24/Getting-Started-with-Java-SecurityManager-from-Zero-2/

官方 API 文档说明: https://docs.oracle.com/javase/8/docs/api/java/lang/SecurityManager.html & https://docs.oracle.com/javase/7/docs/technotes/guides/security/permissions.html & https://docs.oracle.com/javase/8/docs/technotes/guides/security/PolicyFiles.html

中文 API 文档: https://www.apiref.com/java8/java/security/AccessController.html

官方技术介绍: https://docs.oracle.com/javase/8/docs/technotes/guides/security/spec/security-specTOC.fm.html

简单聊聊 SecurityManager: https://juejin.cn/post/7312818418595004426 & https://juejin.cn/post/6844903657775824910#heading-14

Java 安全之 SecurityManager: https://nicky-chen.github.io/2018/07/13/java-securitymanager/

AccessController doPrivileged 使用: https://blog.csdn.net/xyw591238/article/details/51900275 & https://www.cnblogs.com/liruilong/p/14810513.html

API 部分: https://www.cnblogs.com/qisi/p/security_manager.html

Java 沙箱绕过: https://www.anquanke.com/post/id/151398#h3-5

原文始发于微信公众号(Heihu Share):Java 安全 | SecurityManager

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年6月7日23:44:33
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Java 安全 | SecurityManagerhttp://cn-sec.com/archives/4144688.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息