I am a .NET student and currently we are learning about Application Domains.
We were given the following example code (for .NET 3.5). As expected, it throws a SecurityException. Note: TestApp.exe is added as a reference in the project.
Dim file As String = "TestApp.exe"
Dim hostEvidence As Object() = {New Zone(SecurityZone.Internet)}
Dim appDomainEvidence As Evidence = New Evidence(hostEvidence, Nothing)
Dim d As AppDomain = AppDomain.CreateDomain("MyDomain", appDomainEvidence)
d.ExecuteAssembly(file)
When trying to run this in VS2010 under .NET 4.0 I run into a problem.
First it shows a warning
'Public Sub New(hostEvidence() As Object, assemblyEvidence() As Object)' is obsolete: 'This constructor is obsolete. Please use the constructor which takes arrays of EvidenceBase instead.'.
I change the type of hostEvidence to EvidenceBase() and the warning is gone.
However, when trying to run the application it gives an error.
This method implicitly uses CAS policy, which has been obsoleted by the .NET Framework. In order to enable CAS policy for compatibility reasons, please use the NetFx40_LegacySecurityPolicy configuration switch. Please see http://go.microsoft.com/fwlink/?LinkID=155570 for more information.
I have viewed the page, followed the link to How to: Run Partially Trusted Code in a Sandbox and read http://blogs.msdn.com/shawnfa/archive/2009/05/27/coding-with-security-policy-in-net-4-0-implicit-uses-of-cas-policy.aspx but I'm having trouble understanding all of this.
The code example on MSDN is quite big compared to what I currently have, so any help with changing my code so it works without adding other stuff, will be very appreciated.
As it says in the link you provided, .NET is no longer supporting the policy portion of the code access security framework, as of version 4.0.
In other words, your lesson is about .NET 3.5 and does not pertain to the 4.0 framework. The solution is to revert to your original code and configure your project to target the 3.5 framework (you can still use Visual Studio 2010).
.
Related
Scenario:
My company has a legacy (read that as 32 bit) windows form application that will be around for quite some time in the future. This application uses an embedded web browser control that is supplied pages that are contained within the database that it maintains. It was built like this so we could extend/modify as needed. I say this so that I can validate that security is not a concern. Only the application and developers with the correct tools have access to the pages or database. The application is only available inside the office.
There are some processes that I need to accomplish using ActiveX objects that are embedded within the pages/application. One of the biggest and most annoying thing that happens is the ActiveX security warning when I got to create instances of things like “scripting.filesystemobject”. Example:
Set oFSO = CreateObject("Scripting.FileSystemObject")
My solution is to create a DLL that is installed locally on each machine that needs access to the extended functions, have the all the functions (whole DLL ??) marked as safe so that the web browser control does not present the security warning. I have been searching using google and came across very few examples, and all of which are in C# which is not my strongest language.
I’ve had to convert from C to Vb.Net visual basic to get what I have now. When I go to register my DLL, I get the following error message:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319>regasm
Z:\VBNet2017\APIInternal\APIInternal\bin\Debug\APIinternal.dll /tlb
Microsoft .NET Framework Assembly Registration Utility version 4.8.4084.0
for Microsoft .NET Framework version 4.8.4084.0
Copyright (C) Microsoft Corporation. All rights reserved.
Types registered successfully
RegAsm : error RA0000 : Type 'APIInternal.API.Accupay' has an invalid default COM
interface: 'APIInternal.API.Accupay'
UPDATE: Thank you Hans; the error is gone. I've also made some changes in the source code; I changed the ProgID to something that closely resembles where and what this is for. I'm still having issues in creating the object in VB Script.
This is the output from the current version of the code. This is the code, stripped down for clarity:
Option Strict On
Imports System.Runtime.InteropServices
Imports System.IO
Namespace API
Public Interface IAccupay
<DispId(1)>
Function GetFiles(ByVal Folder As String) As List(Of String)
End Interface
<Guid("8B4B5CEF-8B3A-49A1-9053-E909F82D9E73"),
ProgId("AddIn.Accupay"), ClassInterface(ClassInterfaceType.None),
ComDefaultInterface(GetType(IAccupay)), ComVisible(True)>
Public Class Accupay
Implements IAccupay
Private Function GetFiles(Folder As String) As List(Of String) Implements IAccupay.GetFiles
Return Directory.GetFiles(Folder).ToList
End Function
End Class
I have tried just about every combination of ProgID, Name space, Interface name and class name to get this error to go away without any luck. I do know there are other elements that need to be addressed or added, such as error trapping and, if I’m not mistaken, how to actually implement the ObjectSafetyOption which I still don’t know how to do.
I have been using the Guide at the bottom of this article:
Is it possible to mark an ActiveX object as safe so that IE settings need not be changed?, the second answer, but I haven’t had any success.
Please, can someone point me in the right direction, maybe show me what’s wrong with the code that I have and how to physically implement the ObjectSafteyOption that is needed for the web control. Links, additional reading, code examples or comments on how to get this fixed and working would really be appreciated.
Thank you for reading and any help you send my way, Fred
PS: If you need more information, or have a better solution, please don’t hesitate to reply or comment.
UPDATE:
With the code that I have now, I am able to access the DLL in VB.Net visual basic:
Imports System
Imports APIInternal.API
Module Program
Sub Main(args As String())
Dim API As New Accupay
Dim FileList = API.GetFiles("C:\Windows\")
For Each Item As String In FileList
Console.WriteLine(Item)
Next
End Sub
End Module
However, I still can't seem to get the correct calling for a VB Script/html page:
Set Test = CreateObject("Test.Accupay")
Which returns the VB Script error "ActiveX Component can't create object: Test.Accupay or any other iteration of the parts of the name that I tried. I think part of this is that I don't understand how the creation of the project leads to the creation of the object in a com base environment like VB Script.
Fred
The answer to this problem is two fold: You must target the correct platform (X86) AND use the 32 bit version of regasm. Once I realized this was the issue, I was able to create the DLL and use it's functions in the Web Browser control without the active X warning. One example is I can now open the default browser (in this case, NOT IE/EDGE) from a link within the WB Control and another is to get the contents of a folder for further processing within the WB page.
I am writing a .NET Core 3.1 application that depends on another library (Serilog.Sinks.SQLite) which is attempting to store log data to an SQLite database. Unfortunately, Serilog.Sinks.SQLite does not support passing in a password to System.Data.SQLite via the SQLiteConnectionStringBuilder.Password property (which you provide to the SQLiteConnection constructor) and I would really like that functionality.
The code that Serilog.Sinks.SQLite uses to connect to the database is as follows:
private SQLiteConnection GetSqLiteConnection()
{
var sqlConString = new SQLiteConnectionStringBuilder
{
DataSource = _databasePath,
JournalMode = SQLiteJournalModeEnum.Memory,
SyncMode = SynchronizationModes.Normal,
CacheSize = 500,
PageSize = (int)MaxSupportedPageSize,
MaxPageCount = (int)(_maxDatabaseSize * BytesPerMb / MaxSupportedPageSize)
}.ConnectionString;
var sqLiteConnection = new SQLiteConnection(sqlConString);
sqLiteConnection.Open();
return sqLiteConnection;
}
There are a number of similar posts on StackOverflow about encryption with SQLite stating very convincingly that encryption / password protection of the database is indeed supported by System.Data.SQLite. However, that is not matching my experience.
I grabbed a copy of the Serilog.Sinks.SQLite source in an attempt to prototype a modification to it to support specifying the password. This seems like it should be easy enough to accomplish with the following addition to the above code (specifying the Password property in the connection string):
MaxPageCount = (int)(_maxDatabaseSize * BytesPerMb / MaxSupportedPageSize),
Password = "mypasswordhere"
}.ConnectionString;
Unfortunately, this does not work and results in an exception being thrown on startup with the following message:
Exception has occurred: CLR/System.Data.SQLite.SQLiteException An
unhandled exception of type 'System.Data.SQLite.SQLiteException'
occurred in LoggingWebApi.dll: 'SQL logic error Cannot use "Password"
connection string property: library was not built with encryption
support, please see "https://www.sqlite.org/see" for more information'
What is confusing me the most here are the number of other posts I've found claiming that System.Data.SQLite supports this password and the fact that a .NET Framework 4.6 application from another team in my company is using System.Data.SQLite.dll (though an older version 1.0.111.0) and this Password behavior works fine for them.
My code is targeting netcoreap3.1 and my dependency of Serilog.Sinks.SQLite is targeting netstandard2.0 so that is one obvious difference I see. In my modified version of the Serilog.Sinks.SQLite code, I am referencing System.Data.SQLite.Core as follows (added via otnet add package System.Data.SQLite.Core --version 1.0.113.1):
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.113.1" />
Is there something with .NET Core 3.1 or .NET Standard 2.0 that causes System.Data.SQLite.Core to not support the Password connection string property like everyone else seems to think it supports?
I thought maybe my issue was running on Linux so I tried running on my Windows but it produced the same error.
I did find another post referencing a potentially helpful approach but this sample is not using System.Data.SQLite.Core and instead is using SQLitePCLRaw.bundle_e_sqlcipher and I would prefer to avoid rewriting all of the Serilog.Sinks.SQLite code to use a different SQLite client: https://github.com/paragpkulkarni/SQLiteEncryptionUsingEFCore
It seems that System.Data.SQLite has dropped support for encryption as of version 1.0.113.1 which explains why I haven't been able to get it working:
https://system.data.sqlite.org/index.html/tktview?name=9c330a3e03
This is also mentioned on their News page though it was not clear to me that the Password support was part of the "legacy CryptoAPI Codec":
https://system.data.sqlite.org/index.html/doc/trunk/www/news.wiki
The other team I referred to is using an older version 1.0.111.0 so if you require this support, I guess just don't upgrade...
We have a number of classic ASP websites using a VB6 DLL (COM) object for their functionality in the standard way. The DLL is regsvr32'd and the pages use Server.CreateObject to create an instance of the necessary object in the DLL, which in turn triggers the OnStartPage function of the object being created, passing in the ScriptingContext which we then use to get Request (querystring, form) information, read/update session information and read/write cookie information (etc). For clarification, the way you update/store a cookie value using ScriptingContext is
objSC.Response.Cookies(Key) = Value
In preperation of doing a complete .Net overhaul on the code base (and as a first step), we ran the code through the .Net 2008 VB upgrade tool, which makes a few minor code changes, sets up references to interop libraries (for ADODB, ASPTypeLibrary, CDO, etc) and adds the necessary attributes to allow the .Net object to be exposed to COM, and after a few tweaks here and there guided by comments (todos) left by the upgrade tool, the code is compilable except for anything that tried to update/store a cookie using the above code as now, through the ASPTypeLibrary (Interop), the Response.Cookies collection is readonly (with no obvious way to write a cookie now).
If I comment out the offending line of code, the code compiles, and all I need to do is register this new .Net DLL (and it's interop DLLs) in the GAC, use regasm to register it through COM and the classic ASP sites continue working as if nothing happened (except for writing cookies), using Server.CreateObject to create what it thinks is a COM object, triggering the call to OnStartPage, passing in the ScriptingContext.
So although the code base is "upgraded" to .Net it is using a lot of interop libraries to continues working as before, including using the ASPTypeLibrary.ScriptingContext object, as this is what the classic ASP pipeline exposes.
Does anyone know how to write/store a cookie in this scenario?
Need to convert cookie item to IWriteCookie interface. Then it will be writable.
Imports ASPTypeLibrary
Public Class Test
Private oContext As ASPTypeLibrary.ScriptingContext
Private oResponse As ASPTypeLibrary.Response
Public Sub OnStartPage(e As ScriptingContext)
oContext = e
oResponse = oContext.Response
With CType(oResponse.Cookies("fromdotnet"), IWriteCookie)
.Item = String.Format("hello from .Net : {0}", Date.UtcNow())
'.Domain = ""
'.Path = "/"
'.Secure = False
End With
End Sub
End Class
You may want to check out other interfaces such as IReadCookie, IStringList, IRequestDictionary etc.
With note that:
Full trust for the immediate caller. This member cannot be used by partially trusted code.
there is another option : ContextUtil.GetNamedProperty Method
System.EnterpriseServices.ContextUtil.GetNamedProperty("Response").Cookies("fromdotnet") = "hello"
I'm using Silverlight 4 OOB & elevated trust.
I need to get all the filenames on specific directory & populate an object List(Of String)
The compiler throws an error "Method not found" on .Getfiles() method.
Dim files() As String = System.IO.Directory.Getfiles(Path) 'this line is failing..
Help!
The GetFiles is marked as "Security Critical" and therefore cannot be used from your code.
You will want to use the EnumerateFiles method instead. GetFiles is sooo .NET 1.0, EnumerateFiles is much slicker, even in the full framework you'd want avoid this older Array returning API if you can.
As far as I know you cannot directly access the whole hard drive using Silverlight OOB.
Quoting from Silverlight site:
When running in a trusted environment, you can access only files in
user folders, specifically the MyDocuments, MyMusic, MyPictures, and
MyVideos folders. Although this makes sense from a security point of
view, it’s limiting. You want to enable the user to drag their data
from any location. As it stands right now, if you try to drop a file
from a location other than stated above, Silverlight will throw a
security error.
Please refer to this link for details on how to work with the hard drive using Silverlight OOB:
http://www.silverlight.net/learn/overview/out-of-browser-applications/advanced-silverlight-out-of-browser-introduction#Exercise3
The following test case passes in .NET 4.0:
var fiT = new FileInfo("myhappyfilename");
Assert.IsNotNull(fiT);
... but fails in Silverlight 4.0 with the following error:
System.ArgumentNullException: Value cannot be null.
Parameter name: format
at System.String.Format(IFormatProvider provider, String format, Object[] args)
at System.Environment.GetResourceString(String key, Object[] values)
at System.IO.FileSecurityState.EnsureState()
at System.IO.FileInfo.Init(String fileName, Boolean checkHost)
at System.IO.FileInfo..ctor(String fileName)
Either the failure is a bug in SL 4.0, or the non-failure is a bug in .NET 4.0. Anyone know which it is?
(For the record, I'm running SL 4.0 on VS 2010 RC, which may be contributing to the problem).
See the MSDN documentation for FileInfo for Siverlight 4:
When it is called by an elevated-trust
application, provides instance methods
for the creation, copying, deletion,
moving, and opening of files, and aids
in the creation of FileStream objects.
This class cannot be inherited.
Chances are your application isn't running with elevated trust. If you want to access those restricted methods, it'll need to be.
As to why it's returning a null - that may well be a bug, possibly an improperly propagated SecurityException. Then again, it may be as designed - the docs are also still pre-release. EDIT: gabe's answer is most likely correct on this point.
Since you generally can't access the filesystem from Silverlight (you need a fully-trusted OOB app), it looks like SL4 is trying to throw an exception, but is failing because the text for that exception isn't available in the SL4 beta. Presumably you would get the correct exception once SL4 is released.