How to bypass Internet Explorer Enhanced Security when using embedded WebBrowser control? - webbrowser-control

i have a native Windows application that embeds the WebBrowser, i.e.
CLSID_WebBrowser
8856F961-340A-11D0-A96B-00C04FD705A2
Shell.Explorer.2
Unfortunately, when running on Windows Servers, the Internet Explorer Enhanced Security mode interferes with the WebBrowser control, causing it to not render at all:
In this case, the UI of the software is driven as a WebBrowser control - making the software unusable.
i could disable Internet Explorer Enhanced Security mode, but that is not practical.
How can i instruct Internet Explorer browser to allow an embedded browser to render without the security dialog?
Note: i would have suggested adding about:security_Application.exe to the Trusted Zones list"
Sadly, that will require DRP/FRP validation, an ISO security assessment, and the security group will have to be called in to make the change. In addition, an RFC will need to be created so KPMG won't have hissy-fit next audit. i was hoping for the "good" solution.
See also
Customizing (disabling) security settings for IE control
Custom IInternetSecurityManager not being called with dialogs

You can specify a different URL. For example you can extract the content to a temp file and navigate to it. This will not put your content in the trusted zone, but it is better than the internet zone you get for the about protocol.
If you do not want to save the content, you can first navigate to about:blank, then in DocumentComplete, QI the document for IPersistMoniker, and call Load with a TInterfacedObject that basically simulates a url moniker.
The IMoniker.GetDisplayName implementation needs to return the URL. The url needs to be in a trusted zone.
IMoniker.BindToStorage implementation needs to send back a reference to a TMemoryStream when IStream is asked.
There's a third way, write a process-wide security manager that puts your url in a trusted zone.
The solution is to implement your own Internet Security Manager service creating an object that implements IInternetSecurityManager (see MSDN: Implementing a Custom Security Manager). There are five security zones:
Local: URLZONE_LOCAL_MACHINE (0)
Intranet: URLZONE_INTRANET (1)
Trusted: URLZONE_TRUSTED (2)
Internet: URLZONE_INTERNET (3)
Restricted: URLZONE_UNTRUSTED (4)
The only method you really need to worry about is MapUrlToZone:
TEmbeddedSecurityManager = class(TInterfacedObject, IInternetSecurityManager)
public
//...
function MapUrlToZone(pwszUrl: LPCWSTR; out dwZone: DWORD; dwFlags: DWORD): HResult; virtual; stdcall;
//...
end;
This method checks if the Url starts with about:security
about:security_Contoso.exe
and if so, returns that the zone should be Local:
function TEmbeddedSecurityManager.MapUrlToZone(pwszUrl: LPCWSTR; out dwZone: DWORD; dwFlags: DWORD): HResult;
var
url: UnicodeString;
begin
Result := INET_E_DEFAULT_ACTION;
{
https://msdn.microsoft.com/en-us/library/ms537133(v=vs.85).aspx
}
url := pwszUrl;
{
When IE Enchanced Security is enabled, the url goes from
about:blank_xxxx
to
about:security_xxxx
In that case we will put the page in the "Local" zone
}
if url.StartsWith('about:security') then
begin
dwZone := URLZONE_LOCAL_MACHINE; //Local
Result := S_OK;
end;
end;
Every other method must return INET_E_DEFAULT_ACTION (i.e. not S_OK nor E_NOTIMPL), e.g.:
function TEmbeddedSecurityManager.SetSecuritySite(Site: IInternetSecurityMgrSite): HResult;
begin
Result := INET_E_DEFAULT_ACTION;
end;
You give the embedded WebBrowser this service when it calls IServiceProvider.QueryService. In the case of Delphi's TEmbeddedWB control, it is exposed in the OnQueryService event:
function TForm1.EmbeddedWBQueryService(const rsid, iid: TGUID; out Obj: IInterface): HRESULT;
var
sam: IInternetSecurityManager;
begin
Result := E_NOINTERFACE;
//rsid ==> Service Identifier
//iid ==> Interface identifier
if IsEqualGUID(rsid, IInternetSecurityManager) and IsEqualGUID(iid, IInternetSecurityManager) then
begin
sam := TEmbeddedSecurityManager.Create;
Obj := sam;
Result := S_OK;
end;
end;

Maybe you could consider to load a different embedded browser. There is:
WebKit: http://www.webkit.org/
SWT (eclipse)

Related

Inno Setup: Iterate/Enumerate through Firewall Rules / IEnumVariant

I have a similar question like Daniel Rogers about how to declare an IEnumVariant in Inno Setup.
Declare an OleVariant and IEnumVariant in Inno Setup
I'm writing some extra functionality for our setup, in this case I want to add and remove firewall rules during install/uninstall. There are plenty good pointers with examples on the internet to do that. So that's not the problem, it's already done.
But now I want to iterate/enumerate the existing firewall rules but that's the part where I'm struggling with :-( I can't get it to work, unfortunately Inno Setup doesn't recognize the IEnumVariant type so the examples who's are
written in Delphi are not going to work.
If I lookup the Microsoft API documentation about the INetFwRules interface
https://learn.microsoft.com/en-us/windows/win32/api/netfw/nn-netfw-inetfwrules then it looks like it that the only
way to enumerate/iterate is to use the _NewEnum function. (which is returning an IEnumVariant)
So does anybody have some pointers (or mini example) to work around or deal with the above problem?
I also have some issue's when I'm trying to get one single rule through the FwRules.Item function, Inno Setup just keeps saying
"Ongeldig aantal parameters" (something like "invalid parameter count").
var
lcFwPolicy : Variant;
lcFwRules : Variant;
lcFwRule : Variant;
//lcEnum : IVariantEnum;
begin
try
lcFwPolicy := CreateOleObject('HNetCfg.FwPolicy2');
lcFwRules := lcFwPolicy.Rules;
lcFwRules.Item('a fwrule name', lcFwRule); <----- this call is causing "invalid parameter count"
except
Log(GetExceptionMessage);
Log('>>> FirewallRuleExists Exception !!!');
end;
end;
But the most important part of my question is about the enumeration of the firewall rules, if that is possible then the other question is less important.
I'll hope there is somebody out there with the golden solution/workaround.

_ in variable name google apps script? [duplicate]

In Google apps script documentation, there is a page about Private functions on server side. That should explain that without private functions, the server code is visible from the user browser.
Can anybody explain how you can see such server side functions in a browser ?
Thanks
See : https://developers.google.com/apps-script/guides/html/communication#private_functions
The server code is never visible on the user's browser, only the functions names. Private functions hides those names, but more importantly they remove the ability from the frontend to call them directly.
In other words, private functions allow you to define your backend entry-points, preventing a malicious user to bypass some checks you might have and call your "internal" functions directly.
To showcase how easy it is to see the name and call any non-private backend function, I've put up this example where we inspect the google.script.run object:
function myFunction() {}
function anotherFunction() {}
function privateFunction_() {}
function doGet() {
return HtmlService.createHtmlOutput(
'<p id="output"></p>'+
"<script>var s = ''; for( var prop in google.script.run ) s+=prop+'<br>';"+
"document.getElementById('output').innerHTML = s;</script>"
);
}
Here's this example published:
https://script.google.com/macros/s/AKfycbzk0d03iB1O3vVYVD_U7eONM357iOPlAn7RFxAeZKx34q1Ones/exec
And its source code (same as above):
https://script.google.com/d/1WMY5jWblGl8U84WvVU_mZjHDg-6rGOoOPnKMF6m2bS_V-2g6IChBVDrg/edit
-- to address a question in the comments
The doGet function cannot be made private since its name is fixed/predefined. But that is not really a problem as this function is supposed to be an entry point anyways, and since you expect it to be called from the users' browsers and can do your parameters checks and such accordingly.

DWScript Write/Read a simple text file

I would like to write/read a simple text file using dwscript.
My code is here below... but I am non able to get it run, please someone might help...:
(I am using the Simple.exe in the Demos folder of DWS installation)
// uses Classes;
{$INCLUDE_ONCE 'c:/.../System.Classes.pas'}
var
s: TFileStream;
o: string; // out
i: integer;
f: word; // flag
f := fmOpenReadWrite;
if not FileExists('C:\Temp\Junkfile.txt') then
f := f or fmCreate;
s := TFileStream.Create('C:\Temp\Junkfile.txt', f);
try
s.Position := s.Size; // will be 0 if file created, end of text if not
for i := 1 to 10 do begin
o := Format('This is test line %d'#13#10, [i]);
s.Write(o[1], Length(o) * SizeOf(Char));
end;
finally
s.Free;
end;
By default the script engine keeps everything sand-boxed and nothing that gives access outside the sandbox is exposed. So if you want to give access to arbitrary files to script you need to expose functions & classes to achieve it (through TdwsUnit f.i.).
Also it won't compile the Delphi classes unit, DWScript is not meant to be an alternative to the Delphi compiler, but to offer scripting support, ie. allow end users to run code in a way over which you have full control over what they can do, and that can't crash or corrupt the host application (that last point being the key differentiation with the other notable Pascal scripting engines).
You can use dwsFileFunctions to get basic file I/O support, in which case an equivalent to the file creation portion of your code would be something like
var f := FileCreate('C:\Temp\Junkfile.txt');
for var i := 1 to 10 do
FileWrite(f, Format('This is test line %d'#13#10, [i]));
FileClose(f);

Detect if printer support duplex programmatically using obj-c

I have been stumped by this for the last few days. I need to detect if a printer support duplex printing.
I have had partial success using code like:
NSPrinter * printer = [NSPrinter printerWithName:pname];
[printInfo setPrinter:printer];
PMPrintSettings settings = printInfo.PMPrintSettings;
PMDuplexMode pmDuplexMode = 0;
OSStatus status = PMGetDuplex(settings, &pmDuplexMode);
supportsDuplex = (status >= 0);
But this only work if I captured a full printerConfig through an NSPrintPanel. What I need is a way to detect if a printer with a specific name support duplex without requiring the user to 1st open a panel. I would like to do if for any printer defined on the local Mac. Any help is appreciated!
In your code snippet, I doubt that it's correct to interpret positive status as indicating support. In general, any value other than zero (noErr) is a failure of some sort.
If you're confident that PMGetDuplex() returns an error for a print settings object when the printer doesn't support duplex, you can try this approach: create a session with PMCreateSession(), obtain a PMPrinter using PMPrinterCreateFromPrinterID() or by searching the array returned from PMSessionCreatePrinterList() for on which matches whatever criteria you want, set the session to use that printer using PMSessionSetCurrentPMPrinter(), create a print settings object with PMCreatePrintSettings(), call PMSessionDefaultPrintSettings() to initialize the print settings from the session, call PMSessionValidatePrintSettings() just for good measure, then call PMGetDuplex() and check the return value.
It might also be worth trying to set a duplex mode with PMSetDuplex() and check the return code and, possibly, calling PMSessionValidatePrintSettings() and checking if it changed that setting.

JFrame in remote between JDK 5 (Server) and 6 (Client - VisualVM)

So I have a little trouble on the opening of a JFrame. I searched extensively on the net, but I really can not find a solution ...
I explained the situation:
I need to develop an application that needs to retrieve information tracking application while meeting new safety standards. For that I use JMX that allows monitoring and VisualVM to see these information.
I therefore I connect without problems (recently ^ ^) to JMX since VisualVM.
There is thus in a VisualVM plugin for recovering information on MBean, including those on Methods (Operations tab in the plugin).
This allows among others to stop a service or create an event.
My problem then comes when I try to display a result of statistics.
In fact, I must show, at the click of a button from the list of methods in the "Operations", a window with a table in HTML (titles, colors and everything else).
For that I use a JFrame:
public JFrame displayHTMLJFrame(String HTML, String title){
JFrame fen = new JFrame();
fen.setSize(1000, 800);
fen.setTitle(title);
JEditorPane pan = new JEditorPane();
pan.setEditorKit(new HTMLEditorKit());
pan.setEditable(false);
pan.setText(HTML);
fen.add(pan);
return fen;
}
I call it in my method:
public JFrame displayHtmlSqlStatOK_VM(){
return displayHTMLJFrame(displaySQLStat(sqlStatOK, firstMessageDate), "SqlStatOK");
}
The method must therefore giving me back my JFrame, but she generates an error:
Problem invoking displayHtmlSqlStatOK_VM : java.rmi.UnmarshalException: error unmarshalling return; nested
exception is:
java.io.InvalidClassException: javax.swing.JFrame; local class incompatible: stream classdesc serialVersionUID =
-5208364155946320552, local class serialVersionUID = -2386951414768123374
I saw on the internet that this was a version problem (Serialization), and I believe strongly that it comes from the fact that I have this:
Server - JDK5 <----> Client (VisualVM) - JDK6
Knowing that I can not to change the server version (costs too important ...) as advocated by some sites and forums.
My question is as follows:
Can I display this damn window keeping my current architecture (JDK5 server side and client side JDK6)?
I could maybe force the issue? Tell him that there's nothing bad that can run my code? Finally I'm asking him but he does not answer me maybe to you he will tell you ... (Yes I crack ^^).
Thank you very much to those who read me and help me!
If you need more info do not hesitate.
EDIT
The solution to my problem might be elsewhere, because in fact I just want a table with minimal formatting (this is just for viewing application for an for an officer to have his little table him possibly putting critical data in red...).
But I have nowhere found a list of types that I can return with VisualVM ... This does not however seem to me too much to ask.
After I had thought of a backup solution, which would be to create a temporary HTML file and open it automatically in the browser, but right after that is perhaps not very clean ... But if it can work ^^
I am open to any area of ​​research!
It looks like you are sending instance javax.swing.JFrame over the JMX connection - this is a bad idea.
Well good I found myself, as a great :)
Thank you bye!
..........
Just kidding of course I will give the solution that I found ^ ^
So here's what I did:
My display to be done on the client (normal...) my code to display a JFrame that I had set up on the server was displayed obviously ... On the server xD
I didn't want to change the customer (VisualVM) to allow users maximum flexibility. However I realized that to display my HTML table to be rendered usable (with colors and everything) I had to change the client (as JMX does not support the type JFrame as type back an operation).
My operation running from the MBeans plugin for VisualVM, it was necessary that I find the source code for it to say "Be careful if you see that I give you the HTML you display it in a JFrame".
Here is my approach:
- Get the sources
The link SVN to get sources VisualVM is as follows:
https: //svn.java.net/svn/visualvm~svn/branches/release134
If like me you have trouble with the SVN client includes in NetBeans because you are behind a proxy, you can do it by command line:
svn --config-option servers:global:http-proxy-host=MY_PROXY_HOST --config-option servers:global:http-proxy-port=MY_PROXY_PORT checkout https: //svn.java.net/svn/visualvm~svn/branches/release134 sources-visualvm
Putting you on your destination folder of course (cd C:\Users\me\Documents\SourcesVisualVM example).
- Adding the platform VisualVM
NetBeans needs the platform VisualVM to create modules (plugins) for it. For this, go to "Tools" -> "NetBeans Platforms".
Then click "Add Platform ..." at the bottom left of the window and select the folder to the bin downloaded at this address: http:// visualvm.java.net/download.html
You should have this:
http://img15.hostingpics.net/pics/543268screen1.png
- Adding sources in the workspace (NetBeansProjects)
Copy/paste downloaded sources (SVN from the link above) to your NetBeans workspace (by default in C:\Users\XXX\Documents\NetBeansProjects).
- Ouverture du projet du plugin MBeans
In NetBeans, right click in the Project Explorer (or go to the menu "Files") and click "Open Project ...".
You will then have a list of projects in your workspace.
Open the project "mbeans" found in "release134" -> "Plugins", as below:
http://img15.hostingpics.net/pics/310487screen2.png
- Changing the file "platform.properties"
To build plugin you must define some variables for your platform.
To do this, open the file platform.properties in the directory release134\plugins\nbproject of your workspace.
Replace the content (by changing the paths compared to yours):
cluster.path=\
C:\\Program Files\\java6\\visualvm_134\\platform:\
C:\\Program Files\\java6\\visualvm_134\\profiler
# Deprecated since 5.0u1; for compatibility with 5.0:
disabled.clusters=
nbjdk.active=default
nbplatform.active=VisualVM_1.3.4
suite.dir=${basedir}
harness.dir= C:\\Program Files\\NetBeans 7.1.2\\harness
- Changing the class XMBeanOperations
To add our feature (displaying an HTML table), you must change the class that processes operations, namely the class XMBeanOperations in package com.sun.tools.visualvm . modules.mbeans.
At line 173, replace:
if (entryIf.getReturnType() != null &&
!entryIf.getReturnType().equals(Void.TYPE.getName()) &&
!entryIf.getReturnType().equals(Void.class.getName()))
fireChangedNotification(OPERATION_INVOCATION_EVENT, button, result);
By :
if (entryIf.getReturnType() != null &&
!entryIf.getReturnType().equals(Void.TYPE.getName()) &&
!entryIf.getReturnType().equals(Void.class.getName())) {
if (entryIf.getReturnType() instanceof String) {
String res = result + "";
if (res.indexOf("<html>") != -1) {
JFrame frame = displayHTMLJFrame(res, button.getText());
frame.setVisible(true);
}
else
fireChangedNotification(OPERATION_INVOCATION_EVENT, button, result);
} else
fireChangedNotification(OPERATION_INVOCATION_EVENT, button, result);
}
With the method of creating the JFrame that you place above "void performInvokeRequest (final JButton button)" for example:
// Display a frame with HTML code
public JFrame displayHTMLJFrame(String HTML, String title){
JFrame fen = new JFrame();
fen.setSize(1000, 800);
fen.setTitle(title);
JEditorPane pan = new JEditorPane();
pan.setEditorKit(new HTMLEditorKit());
pan.setEditable(false);
pan.setText(HTML);
fen.add(pan);
return fen;
}
We can see that we already did a test on the return type, if it is a String which is returned, if the case, if we see in this string the balise , then we replace the result of the click by opening a JFrame with the string you put in, what makes us display our HTML code!
- Creating a .nbm
The file .nbm is the deployment file of your plugin. Simply right-click your project (in the Project Explorer) and click on "Create NBM".
Your file .nbm will be created in the folder "build" the root of your project.
- Installing the plugin in VisualVM
To install your plugin, you must just go in VisualVM, go into "Tools" -> "Plugins" tab and then "Downloaded", click "Add Plugins ...". Select your plugin .nbm then click "Install". Then follow the instructions.
Useful Sources
http: //docs.oracle.com/javase/6/docs/technotes/guides/visualvm/
http: //visualvm.java.net/"]http://visualvm.java.net/
http: //visualvm.java.net/api-quickstart.html (Créer un plugin VisualVM avec NetBeans)
Thank you very much for your help Tomas Hurka ;)