WL#2925: Improve our medium/partial trust footprint
Affects: Connector/.NET-6.5
—
Status: In-Documentation
The connector doesn't work correctly under medium or partial trust scenarios. This worklog will correct that via two changes. One we will provide a Permission class that allows hosters to provide MySQL support without opening up generic permissions such as SocketPermission. The second change will be introducing some permission asserts throughout the code. This will enable our code to function correctly when installed in the GAC. We are not really attempting to make our provider work well in medium or partial trust scenarios when not installed in the GAC. Our story to site hosters will be that they need to install our provider in the GAC and then add MySqlClientPermission to their trust policy.
The first required element will be a MySqlClientPermission class. This class will function just like SqlClientPermission. An application or host can include this permission in it's trust policy to allow use of our provider. If this permission is not included, then our connector doesn't function. At the code level, this will essentially be our code issuing a Demand for this permission. Please review the documentation around CAS and demanding a cetain permission. The second part of this worklog will be including impertiave asserts for various permissions throughout the code. An example is SocketPermission. In order to be able to connect to a remote socket, you have to Assert that you have SocketPermission to do do. This will be in code and I *think* you have to qualify every single request by host and by port. We would need to check performance and make sure that this addition doesn't adversely affect performance. We would need additional asserts throughout the code for things like TraceSource (for tracing), for pinvoke (for our named pipe and shared memory code), etc. To test this just create a website and set it's web.config to be in medium trust mode. Then attempt to use the website to do things with our connector. You'll see the areas where security exceptions are thrown due to missing permissions.
1 - Using Connector/Net under Medium Trust and the library installed in the GAC - This documentation covers the implementation released in 6.5.4, 6.6.1, 6.6.2 Connector/Net is enable to work on Medium Trust environments when the library is in the GAC and a proper configuration into the web_mediumtrust.config file is included (as described below). This implementation has the following benefits: --- ISP can use the default medium trust configuration without having to elevate their security or trust level when providing Connector/Net for their clients applications. --- ISP can enhance and customized the access allowed for their MySQL Server defining this at a machine-level Web.config file which makes easy to have a higher security in the use of their shared System resources. --- The MySQLClientPermissions class allows to define specific configurations to which connection string parameters can be used in their hosted applications. --- ISP can define a custom policy file based on the existing Web_MediumTrust.config of the .Net framework. 1.1 Set up for the library when using 6.5.4, 6.6.1, 6.6.2 To set up this approach should be done the following - Install one of these Connector/Net versions: 6.5.4, 6.6.1, 6.6.2 - After installing the library the following configuration should be done: In the Security Classes a definition for the MySqlClientPermission should be added including the version to use (6.5.4 or later).. . . . . . . In the NamedPermissionSets PermissionSet a new entry should be added in order to allow Database connections in the clients applications. . . . . . . Note: The above configuration will give an unrestricted use of settings in all the connections strings of the .net applications. In order to customize or restrict the settings of the connections a specific configuration should be done based in a predefined set of settings. So instead of use the previous configuration some settings need to be added. The following example allows connection strings that use any database, but only on the server specified, with any user and password combination and containing no other connection string keywords: How to use MySQLClientPermissions class to define Database access security policies. MySQLClientPermissions is an implementation based on the abstract class DBDataPermission which allows to explicitly define policies that can be used to give access to users inside an application when using MySQL databases and Connector/Net. Constructors: public MySqlClientPermission(PermissionState permissionState) : Initialize a new instance of the MySqlClientPermission class. Overridden Methods: Add(string connectionString, string restrictions, KeyRestrictionBehavior behavior); IPermission Copy() Examples: The following code throws a Security Exception when the user attempts to make a Connection with a Connection string that doesn't match the policy defined previously: PermissionSet permissionset = new PermissionSet(PermissionState.None); MySqlClientPermission permission = new MySqlClientPermission (PermissionState.None); MySqlConnectionStringBuilder strConn = new MySqlConnectionStringBuilder (conn.ConnectionString); //// Allow connections only to specified database no additional optional parameters permission.Add("server=localhost;User Id=root; database=YOURDATABASENAME;", "", KeyRestrictionBehavior.PreventUsage); permission.PermitOnly(); permissionset.AddPermission(permission); permissionset.Demand(); // this connection should NOT be allowed MySqlConnection dummyconn = new MySqlConnection(); dummyconn.ConnectionString = "server=localhost;User Id=root;database=ADIFFERENTNAME;"; dummyconn.Open(); if (dummyconn.State == ConnectionState.Open) dummyconn.Close(); This example shows how a connection is properly done after setting the Security Policy PermissionSet permissionset = new PermissionSet(PermissionState.None); MySqlClientPermission permission = new MySqlClientPermission (PermissionState.None); MySqlConnectionStringBuilder strConn = new MySqlConnectionStringBuilder (conn.ConnectionString); //// Allow connections only to specified database no additional optional parameters permission.Add("server=localhost;User Id=root;database=YOURDATABASENAME;port=" + strConn.Port + ";", "", KeyRestrictionBehavior.PreventUsage); permission.PermitOnly(); permissionset.AddPermission(permission); permissionset.Demand(); // this conection should be allowed MySqlConnection dummyconn = new MySqlConnection(); dummyconn.ConnectionString = "server=localhost;User Id=root;database=YOURDATABASENAME;port=" + strConn.Port "; dummyconn.Open(); if (dummyconn.State == ConnectionState.Open) dummyconn.Close(); 2 - Using Connector/Net under Medium Trust with the library without installing it in the GAC with 6.5.5, 6.6.4 and further versions You can also have Medium trust support using any of the following versions: 6.5.5, 6.6.3 or further, without installing the library in the GAC and use it from a bin or lib directory included in your solution or project. There are some configurations needed since Medium trust policy doesn't have Socket Permissions supported so you must add it to the medium trust policy. Open the medium trust policy web config file which should be under this folder : (%windir%\Microsoft.NET\Framework\{version} \CONFIG\web_mediumtrust.config (or Framework64 if you're using a 64 bit installation of the Framework) You should add: Inside the SecurityClasses tag: Scroll down and look for the following PermissionSet: Add the following inside this PermissionSet: This configuration will allow that you can use the driver with the tcp protocol which is the default in Windows without having any security issues. This approach only supports the tcp protocol so you cannot use any other type of connection. Also please notice that since the MySQLClientPermissions is not added to the medium trust policy you cannot use it. This configuration is the minimum required in order to work with the Connector without the GAC. 3 - Using Connector/Net under Medium Trust with the library installed in the GAC in 6.5.5, 6.6.3 and further versions If the library is installed in the GAC (versions 6.5.5, 6.6.4) you also need to include the MySqlClientPermissions in the security policy and configure the web_mediumtrust.config file as describe in the Section 1.1. This version introduced a new setting that performs the security asserts by demand when the includesecurityasserts setting is set to true in the Connection String. If the user has his application on a Medium trust Hosting Service he/she must include the includesecurityassert=true setting when opening a Connection to avoid any security issue since the policy for medium trust doesn't include the Socket Permissions, Dns Permissions, Reflection among others. In this case the library should ask their own permissions in order to establish a connection. 3.1 How to use MySQLClientPermissions in 6.5.5, 6.6.4 and further versions Since this version handles the security asserts in a demanding way. The only change to the use of the MySqlClientPermissions class was to add the includesecurityasserts=true setting in the Connection String. Examples: The following code throws a Security Exception when the user attempts to make a Connection by using a Connection string that doesn't match the correct settings. This scenario covers when using MySqlClientPermissions class to define the allowed connection string settings in the application. PermissionSet permissionset = new PermissionSet(PermissionState.None); MySqlClientPermission permission = new MySqlClientPermission (PermissionState.None); MySqlConnectionStringBuilder strConn = new MySqlConnectionStringBuilder (conn.ConnectionString); //// Allow connections only to specified database no additional optional parameters permission.Add("server=localhost;User Id=root; database=YOURDATABASENAME;", "", KeyRestrictionBehavior.PreventUsage); permission.PermitOnly(); permissionset.AddPermission(permission); permissionset.Demand(); // this connection should NOT be allowed MySqlConnection dummyconn = new MySqlConnection(); dummyconn.ConnectionString = "server=localhost;User Id=root;database=ADIFFERENTNAME;includesecurityasserts=true;"; dummyconn.Open(); if (dummyconn.State == ConnectionState.Open) dummyconn.Close(); This example shows how a connection is properly done after setting the Security Policy PermissionSet permissionset = new PermissionSet(PermissionState.None); MySqlClientPermission permission = new MySqlClientPermission (PermissionState.None); MySqlConnectionStringBuilder strConn = new MySqlConnectionStringBuilder (conn.ConnectionString); //// Allow connections only to specified database no additional optional parameters permission.Add("server=localhost;User Id=root;database=YOURDATABASENAME;port=3306;includesecurityasserts=true;", "", KeyRestrictionBehavior.PreventUsage); permission.PermitOnly(); permissionset.AddPermission(permission); permissionset.Demand(); // this conection should be allowed MySqlConnection dummyconn = new MySqlConnection(); dummyconn.ConnectionString = "server=localhost;User Id=root;database=YOURDATABASENAME;port=3306; dummyconn.Open(); if (dummyconn.State == ConnectionState.Open) dummyconn.Close(); Summary: We have two approaches when supporting Medium Trust. One with the Library in the GAC and the other with the library only in a bin or lib folder inside a project or solution. If the library is in the GAC an additional configuration should be done in the medium trust policy. If the library is not in the GAC the only protocol supported is tcp.
Copyright (c) 2000, 2024, Oracle Corporation and/or its affiliates. All rights reserved.