5

Java ポリシー ファイルでは、grant codeBaseどのコードベースにどのパーミッションを付与する必要があるかを構文で指定します。例えば、

grant codeBase "file:/C:/abc.jar" { パーミッション java.security.AllPermission; };

AllPermissionabc.jar 内のコードへの付与

deny同様に、特定の構文に権限を付与する方法はありますか? このような:

deny codeBase "file:/C:/def.jar" { パーミッション java.io.FilePermission; };

内部のコードdef.jarが FilePermission を除く他のすべてのアクセス許可を取得するようにするには?

これは可能ですか?

これはクラスを使用して簡単に実行できることはわかっていますがSecurityManager、ポリシー ファイルのみを使用してこれが可能かどうかを知りたいだけです。

4

4 に答える 4

17

これはほぼ 1 年遅れていることは承知していますが、似たようなことをしようとしていると思います。

Java がグローバル権限を付与しないようにランタイム権限を設定する方法があります。次に、アプリに付与する権限のみを指定できます。重要なのは、以下のオプションを使用してアプリを実行することです。

java -Djava.security.manager -Djava.security.policy==policyFile.txt MyClass

double equals に注意してください-Djava.security.policy==policyFile.txt。二重の等号は、継承されたグローバル アクセス許可に加えてこれらのアクセス許可を使用することを意味する単一の等号とは対照的に、指定されたファイルのアクセス許可のみ==を使用することを意味します。-Djava.security.policy=policyFile.txt

次に、拒否するアクセス許可を除外するポリシー ファイルを作成します。

// policyFile.txt
grant codeBase "file:/C:/abc.jar" {

    // list of permissions minus the ones you want to deny
    // for example, the following would give the application
    // ONLY AudioPermission and AWTPermission.  Other
    // permissions such as java.io.FilePermission would be
    // denied.

    permission javax.sound.sampled.AudioPermission;
    permission java.awt.AWTPermission;

}
于 2012-01-18T05:45:53.070 に答える
9

拒否ルールを含むポリシー ファイルを実装するProgradeライブラリを使用できます。

次の Maven 依存関係をアプリに追加します

<dependency>
    <groupId>net.sourceforge.pro-grade</groupId>
    <artifactId>pro-grade</artifactId>
    <version>1.0</version>
</dependency>

次に、標準のシステム プロパティを使用してアプリケーションで有効にします。

-Djava.security.manager=net.sourceforge.prograde.sm.ProgradeSecurityManager -Djava.security.policy==/path/to/your/application.policy

または、コード内の Policy 実装をプログラムで置き換えることができます。

System.setProperty("java.security.policy","/path/to/your/application.policy");
Policy.setPolicy(new ProgradePolicyFile());

ポリシー ファイルの構文は標準の実装と似ていますが、deny代わりに使用できgrant、キーワードを使用して優先度を変更することもできますpriority(デフォルト値は"deny"後方互換性を維持するため - です)。

たとえば、sth を実行できます。お気に入り:

grant {
    permission java.lang.RuntimePermission "*";
};

deny {
    permission java.lang.RuntimePermission "exitVM.*";
};

他の例はここにあります。

于 2014-01-28T20:52:08.833 に答える
1

いいえ。ポリシーファイルにこのような実装はありません。あなたが本当に必死なら、あなたはあなた自身のシステムを書くことができます。

于 2011-02-15T15:35:50.103 に答える
0

拒否ルールのサポートを達成するための最も関与の少ないアプローチの 1 つは、次のとおりです。

  • Permission通常の肯定的な許可をラップして否定する「否定的な」サブクラスを定義します。と
  • デフォルトをラップしてPolicy、それ(そのラッパー)がそのような権限を理解できるようにします。

DeniedPermissionクラス_

package com.example.q5003565;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.security.BasicPermission;
import java.security.Permission;
import java.security.UnresolvedPermission;
import java.text.MessageFormat;

/**
 * A representation of a "negative" privilege.
 * <p>
 * A <code>DeniedPermission</code>, when "granted" to some <code>ProtectionDomain</code>, represents
 * a privilege which <em>cannot</em> be exercised, regardless of any positive permissions
 * (<code>AllPermission</code> included) possessed. In other words, if a set of granted permissions,
 * <em>P</em>, contains a permission of this class, <em>D</em>, then the set of effectively granted
 * permissions is<br/>
 * <br/>
 * &nbsp;&nbsp;&nbsp;&nbsp;<em>{ P<sub>implied</sub> - D<sub>implied</sub> }</em>.
 * </p>
 * <p>
 * Each instance of this class encapsulates a <em>target permission</em>, representing the
 * "positive" permission being negated.
 * </p>
 * Denied permissions employ the following naming scheme:<br/>
 * <br/>
 * &nbsp;&nbsp;&nbsp;&nbsp;<em>&lt;target_class_name&gt;:&lt;target_name&gt;(:&lt;target_actions&gt;)</em><br/>
 * <br/>
 * where:
 * <ul>
 * <li><em>&lt;target_class_name&gt;</em> is the fully qualified name of the target permission's
 * class,</li>
 * <li><em>&lt;target_name&gt;</em> is the {@linkplain #getName() name} of the target
 * permission,</li>
 * <li><em>(&lt;target_actions&gt;)</em> is, optionally, the {@linkplain #getActions() actions
 * string} of the target permission, and</li>
 * <li>the <em>':'</em> character stands for itself.</li>
 * </ul>
 * A denied permission, having a target permission <em>t</em>, is said to
 * {@linkplain #implies(Permission) <em>imply</em>} another permission <em>p</em>, iff:
 * <ul>
 * <li>p <em>is not</em> itself a denied permission, and <code>(t.implies(p) == true)</code>,
 * or</li>
 * <li>p <em>is</em> a denied permission, with a target <em>t1</em>, and
 * <code>(t.implies(t1) == true)</code>.</li>
 * </ul>
 * <p>
 * It is the responsibility of the policy decision point (e.g., the <code>Policy</code> provider) to
 * take denied permission semantics into account when issuing authorization statements.
 * </p>
 */
public final class DeniedPermission extends BasicPermission {

    private static final String NULL_STR_ARG = "<null>", EMPTY_STR_ARG = "<empty> ";
    private static final long serialVersionUID = 2102974454790623344L;

    private final Permission target;

    /**
     * Instantiates a <code>DeniedPermission</code> that encapsulates a target permission of the
     * indicated class, specified name and, optionally, actions.
     * 
     * @throws IllegalArgumentException
     *             if:
     *             <ul>
     *             <li><code>targetClassName</code> is <code>null</code>, the empty string, does not
     *             refer to a concrete <code>Permission</code> descendant, or refers to
     *             <code>DeniedPermission.class</code> or <code>UnresolvedPermission.class</code>.</li>
     *             <li><code>targetName</code> is <code>null</code>.</li>
     *             <li><code>targetClassName</code> cannot be instantiated, and it's the caller's fault;
     *             e.g., because <code>targetName</code> and/or <code>targetActions</code> do not adhere
     *             to the naming constraints of the target class; or due to the target class not
     *             exposing a <code>(String name)</code>, or <code>(String name, String actions)</code>
     *             constructor, depending on whether <code>targetActions</code> is <code>null</code> or
     *             not.</li>
     *             </ul>
     * @throws SecurityException
     *             if a <code>SecurityManager</code>, <code>sm</code>, is installed, and the invocation
     *             <code>sm.checkPackageAccess(targetClassPackageName)</code> (where
     *             <code>targetClassPackageName</code> is the package of the class referred to
     *             by <code>targetClassName</code>) denies access.
     */
    public static DeniedPermission newDeniedPermission(String targetClassName, String targetName,
            String targetActions) {
        if (targetClassName == null || targetClassName.trim().isEmpty() || targetName == null) {
            throw new IllegalArgumentException("[targetClassName] and [targetName] must not be null or empty.");
        }
        StringBuilder sb = new StringBuilder(targetClassName).append(":").append(targetName);
        if (targetName != null) {
            sb.append(":").append(targetName);
        }
        return new DeniedPermission(sb.toString());
    }

    /**
     * Instantiates a <code>DeniedPermission</code> that encapsulates the given target permission.
     * 
     * @throws IllegalArgumentException
     *             if <code>target</code> is <code>null</code>, a <code>DeniedPermission</code>, or an
     *             <code>UnresolvedPermission</code>.
     */
    public static DeniedPermission newDeniedPermission(Permission target) {
        if (target == null) {
            throw new IllegalArgumentException("[target] must not be null.");
        }
        if (target instanceof DeniedPermission || target instanceof UnresolvedPermission) {
            throw new IllegalArgumentException("[target] must not be a DeniedPermission or an UnresolvedPermission.");
        }
        StringBuilder sb = new StringBuilder(target.getClass().getName()).append(":").append(target.getName());
        String targetActions = target.getActions();
        if (targetActions != null) {
            sb.append(":").append(targetActions);
        }
        return new DeniedPermission(sb.toString(), target);
    }

    private static Permission constructTargetPermission(String targetClassName, String targetName,
            String targetActions) {
        Class<?> targetClass;
        try {
            targetClass = Class.forName(targetClassName);
        }
        catch (ClassNotFoundException cnfe) {
            if (targetClassName.trim().isEmpty()) {
                targetClassName = EMPTY_STR_ARG;
            }
            throw new IllegalArgumentException(
                    MessageFormat.format("Target Permission class [{0}] not found.", targetClassName));
        }
        if (!Permission.class.isAssignableFrom(targetClass) || Modifier.isAbstract(targetClass.getModifiers())) {
            throw new IllegalArgumentException(MessageFormat
                    .format("Target Permission class [{0}] is not a (concrete) Permission.", targetClassName));
        }
        if (targetClass == DeniedPermission.class || targetClass == UnresolvedPermission.class) {
            throw new IllegalArgumentException(
                    "Target Permission class must not be a DeniedPermission itself, nor an UnresolvedPermission.");
        }
        Constructor<?> targetCtor;
        try {
            if (targetActions == null) {
                targetCtor = targetClass.getConstructor(String.class);
            }
            else {
                targetCtor = targetClass.getConstructor(String.class, String.class);
            }
        }
        catch (NoSuchMethodException nsme) {
            throw new IllegalArgumentException(MessageFormat.format(
                    "Target Permission class [{0}]  (String name) or (String name, String actions) constructor.",
                    targetClassName));
        }
        try {
            return (Permission) targetCtor
                    .newInstance(((targetCtor.getParameterCount() == 1) ? new Object[] { targetName }
                            : new Object[] { targetName, targetActions }));
        }
        catch (ReflectiveOperationException roe) {
            if (roe instanceof InvocationTargetException) {
                if (targetName == null) {
                    targetName = NULL_STR_ARG;
                }
                else if (targetName.trim().isEmpty()) {
                    targetName = EMPTY_STR_ARG;
                }
                if (targetActions == null) {
                    targetActions = NULL_STR_ARG;
                }
                else if (targetActions.trim().isEmpty()) {
                    targetActions = EMPTY_STR_ARG;
                }
                throw new IllegalArgumentException(MessageFormat.format(
                        "Could not instantiate target Permission class [{0}]; provided target name [{1}] and/or target [{2}] actions potentially erroneous.",
                        targetClassName, targetName, targetActions), roe);
            }
            throw new RuntimeException(MessageFormat.format(
                    "Could not instantiate target Permission class [{0}] - an unforeseen error occurred, see attached cause for details.",
                    targetClassName), roe);
        }
    }

    /**
     * Instantiates a <code>DeniedPermission</code> that encapsulates a target permission of the class,
     * name and, optionally, actions, collectively provided as the <code>name</code> argument.
     * 
     * @throws IllegalArgumentException
     *             if:
     *             <ul>
     *             <li><code>name</code>'s target permission class name component is empty, does not
     *             refer to a concrete <code>Permission</code> descendant, or refers to
     *             <code>DeniedPermission.class</code> or <code>UnresolvedPermission.class</code>.</li>
     *             <li><code>name</code>'s target name component is <code>empty</code></li>
     *             <li>the target permission class cannot be instantiated, and it's the caller's fault;
     *             e.g., because <code>name</code>'s target name and/or target actions component(s) do
     *             not adhere to the naming constraints of the target class; or due to the target class
     *             not exposing a <code>(String name)</code>, or
     *             <code>(String name, String actions)</code> constructor, depending on whether the
     *             target actions component is empty or not.</li>
     *             </ul>
     * @throws SecurityException
     *             if a <code>SecurityManager</code>, <code>sm</code>, is installed, and the invocation
     *             <code>sm.checkPackageAccess(targetClassPackageName)</code>
     *             (where <code>targetClassPackageName</code> is the package of the class referred to
     *             by <code>name</code>'s target name component) denies access.
     */
    public DeniedPermission(String name) {
        super(name);
        String[] comps = name.split(":");
        if (comps.length < 2) {
            throw new IllegalArgumentException(MessageFormat.format("Malformed [name] argument: {0}", name));
        }
        this.target = constructTargetPermission(comps[0], comps[1], ((comps.length < 3) ? null : comps[2]));
    }

    private DeniedPermission(String name, Permission target) {
        super(name);
        this.target = target;
    }

    /**
     * Checks whether the given permission is implied by this one, as per the
     * {@linkplain DeniedPermission overview}.
     */
    @Override
    public boolean implies(Permission p) {
        if (p instanceof DeniedPermission) {
            return target.implies(((DeniedPermission) p).target);
        }
        return target.implies(p);
    }

    /**
     * Returns this denied permission's target permission.
     */
    public Permission getTargetPermission() {
        return target;
    }

}

DenyingPolicyクラス_

package com.example.q5003565;

import java.security.AccessController;
import java.security.CodeSource;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.Policy;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.security.UnresolvedPermission;
import java.util.Enumeration;

/**
 * Wrapper that adds rudimentary {@link DeniedPermission} processing capabilities to the standard
 * file-backed <code>Policy</code>.
 */
public final class DenyingPolicy extends Policy {

    /*
     * doPrivileged needed just in case there's already a SecurityManager installed at class loading
     * time.
     */
    private static final ProtectionDomain OWN_PD = AccessController
            .doPrivileged((PrivilegedAction<ProtectionDomain>) DenyingPolicy.class::getProtectionDomain);

    private final Policy defaultPolicy;

    {
        try {
            // will fail unless the calling acc has SecurityPermission "createPolicy.javaPolicy"
            defaultPolicy = Policy.getInstance("javaPolicy", null, "SUN");
        }
        catch (NoSuchProviderException | NoSuchAlgorithmException e) {
            throw new RuntimeException("Could not acquire default Policy.", e);
        }
    }

    @Override
    public PermissionCollection getPermissions(CodeSource codesource) {
        return defaultPolicy.getPermissions(codesource);
    }

    @Override
    public PermissionCollection getPermissions(ProtectionDomain domain) {
        return defaultPolicy.getPermissions(domain);
    }

    /**
     * @return <code>true</code> iff:
     *         <ul>
     *         <li><code>permission</code> <em>is not</em> an instance of
     *         <code>DeniedPermission</code>,</li>
     *         <li>an <code>implies(domain, permission)</code> invocation on the system-default
     *         <code>Policy</code> yields <code>true</code>, and</li>
     *         <li><code>permission</code> <em>is not</em> implied by any <code>DeniedPermission</code>s
     *         having potentially been assigned to <code>domain</code>.</li>
     *         </ul>
     */
    @Override
    public boolean implies(ProtectionDomain domain, Permission permission) {
        if (OWN_PD.equals(domain)) {
            /*
             * Recursive invocation due to a privilege-requiring method we invoked. If you're uncomfortable with
             * this, get rid of it and grant (via .policy) a RuntimePermission "accessClassInPackage.*" to
             * OWN_PD.
             */
            return true;
        }
        if (permission instanceof DeniedPermission) {
            /*
             * At the policy decision level, DeniedPermissions can only themselves imply, not be implied (as
             * they take away, rather than grant, privileges). Returning true for a deny rule would be
             * more confusing than convenient.
             */
            return false;
        }

        if (!defaultPolicy.implies(domain, permission)) {
            // permission not granted--no need to check whether denied
            return false;
        }

        /*
         * Permission granted--now check whether there's an overriding DeniedPermission. The following
         * assumes that defaultPolicy (its wrapped PolicySpi) is a sun.security.provider.PolicySpiFile
         * (other implementations might not support #getPermissions(ProtectionDomain)
         * and/or handle resolution of UnresolvedPermissions differently).
         */

        Enumeration<Permission> perms = defaultPolicy.getPermissions(domain).elements();
        while (perms.hasMoreElements()) {
            Permission p = perms.nextElement();
            /*
             * DeniedPermissions will generally remain unresolved, as no code is expected to check whether other
             * code has been "granted" such a permission.
             */
            if (p instanceof UnresolvedPermission) {
                UnresolvedPermission up = (UnresolvedPermission) p;
                if (up.getUnresolvedType().equals(DeniedPermission.class.getName())) {
                    // force resolution
                    defaultPolicy.implies(domain, up);
                    // evaluate right away, to avoid reiterating over the collection
                    p = AccessController.doPrivileged(
                            (PrivilegedAction<Permission>) () -> new DeniedPermission(up.getUnresolvedName()));
                }
            }
            if (p instanceof DeniedPermission && p.implies(permission)) {
                // permission denied
                return false;
            }
        }
        // permission granted
        return true;
    }

    @Override
    public void refresh() {
        defaultPolicy.refresh();
    }

}

使用法

DeniedPermissions をプレーンな古い付与ルールに埋め込むだけです。たとえば、次のルールは、名前が「user.」で始まるシステム プロパティを読み取る機能以外のすべてsome.jarのクラスに付与します。

grant codeBase "file:/home/your_user/classpath/some.jar" {
    permission java.security.AllPermission;
    permission com.example.q5003565.DeniedPermission "java.util.PropertyPermission:user.*:read";
};

次に、DenyingPolicyビアを取り付けPolicy.setPolicy(new DenyingPolicy());ます。

警告:前の回答のコメントで述べたように、意味的には正しいですが、上記の例は効果がありませSecurityPermission "setPolicy"DeniedPermission。これが発生しないようにするには、 からパーミッションを差し引くAllPermissionのではなく、 から差し引くことを検討してくださいAllSafePermission。ここでは、既知のサンドボックス無効化パーミッション1を除くすべてAllSafePermissionの が定義されています。implies

ノート

  • (String)標準のターゲット名とアクションの規則に従い、 and/or(String, String)コンストラクターを公開し、 を適切にオーバーライドする限り、任意のアクセス許可を拒否されたアクセス許可でラップできますimplies(Permission)
  • 一度に複数のアクセス許可を拒否するには:
    • implies拒否されるパーミッションである通常のパーミッション サブクラスを作成します。
    • ポリシー構成から、実装のインスタンスを参照して、拒否されたアクセス許可を「付与」します。
  • は、保護ドメインに静的に割り当てられたパーミッション (クラスパスから生成されたコードにデフォルトで付与されるパーミッションなど) が付与されることを妨げDenyingPolicy ません。一般に、このようなパーミッションの評価は、ポリシーによって維持されるパーミッションの評価の前に行われるためです。これらの権限も拒否するには、次のものに置き換える必要があります。 RuntimePermission "exitVM.*"ClassLoader
    • そもそもアクセス許可を付与しないか、または
    • ロードするクラスを、次のようProtectionDomainにオーバーライドするサブクラスのインスタンスにマップimplies(Permission)します。
      • 常にポリシーに委任する、または
      • DeniedPermissionと同様の方法で を処理しDenyingPolicyます。

1: そのような権限のリストについては、Maass, M. (2016) などを参照してください。サンドボックスを効果的に適用するための理論とツール。、表 3.1 (47 ページ)。

于 2017-08-30T12:33:42.963 に答える