JSF MAC did not verify! error on clustered environment [duplicate] - tomcat8

I have a JSF application that uses Mojarra 2.2.9
and is deployed on WebSphere 8.5.5.4 on clustered environement
and javax.faces.STATE_SAVING_METHOD is set to client.
Even though all my application beans are request scoped, sometimes when the user session is valid and the user is doing post request on a page he gets ViewExpiredException. What may be causing this issue and how can I solve it?
Will changing the javax.faces.STATE_SAVING_METHOD to server solve it? If so, what is the impact of doing this on memory?
Also, does this have anything to do with cluster environement and maybe there's some missing configuration on the Websphere that will solve the issue?

This will happen if the client side state is encrypted by one server and decrypted by other server and the servers don't use the same AES key for this. Normally, you should also have seen below warning in server log:
ERROR: MAC did not verify
You need to ensure that you have set jsf/ClientSideSecretKey in web.xml with a fixed AES key, otherwise each server will (re)generate its own AES key during startup/restart (which is used during encrypting view state).
<env-entry>
<env-entry-name>jsf/ClientSideSecretKey</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>[AES key in Base64 format]</env-entry-value>
</env-entry>
You can use this snippet to generate a random AES256 (32bit) key in Base64 format.
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256); // Use 128 for 16bit key.
String key = Base64.getEncoder().encodeToString(keyGen.generateKey().getEncoded());
System.out.println(key); // Prints AES key in Base64 format.
In case you get Java Security: Illegal key size or default parameters? error, install the cryptography extension as instructed in the link, or else generate a random AES128 (16bit) key instead.
After having the key, make absolutely sure you don't publish/opensource your key.
Further you also need to ensure you have added <distributable /> tag to web.xml so JSF will perform more agressive session dirtying and the HTTP sessions (including view scoped beans themselves!) are properly synced across servers.
Another probable cause of ViewExpiredException with client side state saving is that you've set the Mojarra-specific context param com.sun.faces.clientStateTimeout in web.xml which represents the time in seconds before an incoming client side state is considered expired. This is however unlikely the case here as that context param has a rather self-explaining name which you would have spotted by just glancing over web.xml.
See also:
com.sun.faces.ClientStateSavingPassword - recommendations for actual password?
javax.faces.application.ViewExpiredException: View could not be restored

You must have the distributable tag in your web.xml as mentioned by balusc

Related

Netty: Safe SSL implementation

I basically tried to implement Netty's build in SSLHandler. I had no problems until i implemented the Client-Side SSL.
I tried everything out any neither of all tries actually checked an incoming certificate of a Server. I could basically connect me to invalid SSL Servers.
I only saw codes like these on the internet:
pipeline.addLast("ssl", SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build().newHandler(channel.alloc(), UserConnection.SERVER_API_DOMAIN, UserConnection.SERVER_CONNECTION_PORT));
Any Ideas?
If you pass in .trustManager(null) , you get the system default which should check certificates based on the default root certs you have on your system.
To quote docs https://netty.io/4.1/api/io/netty/handler/ssl/SslContextBuilder.html#trustManager-java.lang.Iterable-
:
Trusted certificates for verifying the remote endpoint's certificate, null uses the system default
Of course, you could also leave out the .trustManager(...) call altogether, since the default is null

Marklogic http post using ssl

I am trying to do a xdmp:http-post to a third party URL using the Marklogic (v7.0) query console. The URL is a https:// url and I was able to install the necessary certificate from the admin console. When I run the post, I am receiving the following error:
[1.0-ml] SVC-SOCCONN: xdmp:http-post("https://xxxxx.............", ()) -- Socket connect error: SSL_connect XXX.XXX.XXX.XX:60855-XX.XX.X.XX:443: key size too small (0x0506706e); DH lib (0x14098005)
Can you please assist me here as to what I might be doing wrong? Do I need to follow any additional steps apart from installing the certificate?
Please let me know if I need to supply additional information.
The server's certificate is using a key size that is too small, and therefore considered to be insecure. Since the host name suggests it's a dev machine, the best thing would be to have them use a longer key if you can.
If that's not possible, you can disable FIPS mode on your MarkLogic server. That can be done through the Admin UI by navigating to http://your.host.name:8001/cluster-admin.xqy?section=cluster&local-cluster=true and setting "ssl fips enabled" to false. Be aware that if you do this, the server will allow you to use ciphers and key lengths that are considered weak.

How to call Apache NMS from in a sandbox?

I'm trying to call Apache ActiveMQ NMS Version 1.6.0 from my code ('IntPub') that must run in a sandbox in a .NET 4.0 environment for security reasons. The program that creates the sandbox makes my code 'partially trusted' and therefore 'security-transparent' which seems to mean that it can't create a ConnectionFactory (see error log below) because NMS seems to be 'security-critical'. Here's the code that's causing this error:
connecturi = new Uri("tcp://my.server.com:61616");
var connectionFactory = new ConnectionFactory(connecturi);
I also tried this instead with similar results:
connecturi = new Uri("activemq:tcp://my.server.com:61616");
var connectionFactory = NMSConnectionFactory.CreateConnectionFactory(connecturi);
Since I can't change the security level of my assembly (the sandbox prevents it) is there a way to make NMS run as 'safe-critical' so it can be called by 'security-transparent' code? Would I have to recompile it to do so, or does NMS do some operation that would never be considered 'safe-critical?
I appreciate any help or suggestions...
Assembly 'IntPub, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6fa620743b8dc60a' is partially trusted, which causes the CLR to make it entirely security transparent regardless of any transparency annotations in the assembly itself. In order to access security critical code, this assembly must be fully trusted.Detail:
<OrganizationServiceFault xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/xrm/2011/Contracts">
<ErrorCode>-2147220956</ErrorCode>
<ErrorDetails xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
<Message>Unexpected exception from plug-in (Execute): Test.Client: System.MethodAccessException: Attempt by security transparent method 'Test.Client.Execute(System.IServiceProvider)' to access security critical method 'Apache.NMS.ActiveMQ.ConnectionFactory..ctor(System.Uri)' failed.
From the error message attributes, it looks like you're running a Dynamics CRM 2011 plugin in sandbox mode, which has some very specific rules about what you can and can't do. In particular, you're only allowed to make network connections via HTTP and HTTPS, so attempting raw TCP sockets will definitely fail.
Take a look at this MSDN page on Plug-in Isolation, Trusts, and Statistics. It looks like there may be a way to relax the network restrictions by modifying a system registry entry to include tcp, etc, in the regex value. Below is an excerpt from the page. Note: I have not done this myself, so can't say for sure it'll work.
Sandboxed plug-ins and custom workflow activities can access the
network through the HTTP and HTTPS protocols. This capability provides
support for accessing popular web resources like social sites, news
feeds, web services, and more. The following web access restrictions
apply to this sandbox capability.
Only the HTTP and HTTPS protocols are allowed.
Access to localhost (loopback) is not permitted.
IP addresses cannot be used. You must use a named web address that requires DNS name resolution.
Anonymous authentication is supported and recommended. There is no provision for prompting the logged on user for credentials or saving those credentials.
These default web access restrictions are defined in a registry key on
the server that is running the Microsoft.Crm.Sandbox.HostService.exe
process. The value of the registry key can be changed by the System
Administrator according to business and security needs. The registry
key path on the server is:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSCRM\SandboxWorkerOutboundUriPattern
The key value is a regular expression string that defines the web access restrictions.
The default key value is:
"^http[s]?://(?!((localhost[:/])|([.])|([0-9]+[:/])|(0x[0-9a-f]+[:/])|(((([0-9]+)|(0x[0-9A-F]+)).){3}(([0-9]+)|(0x[0-9A-F]+))[:/]))).+";*
By changing this registry key value, you can change the web access for sandboxed plug-ins.

X.509 : Server not able to extract user information from client certificate

I have jetty working with SSL set up, client and server certificates (X.509) provided as required according to Spring Security and upto this it all seems working fine and verified by logs.
Now! The problem is when I access a secure page, client(Chrome) is sending a certificate and server is receiving it successfully but after that it is returning me an empty user. Does any body have any idea what is happening here?
I am providing some information about what I am trying here :
Environment
Windows/Jetty (version: 8.1.11.v20130520)/Spring Security (3.2.0)
Connector in jetty (version: 8.1.11.v20130520)
<connector implementation="org.eclipse.jetty.server.ssl.SslSocketConnector">
<port>9443</port>
<keystore>src/test/resources/server.jks</keystore>
<needClientAuth>true</needClientAuth>
<keyPassword>password</keyPassword>
<password>password</password>
</connector>
Security Configuration file
<sec:x509 subject-principal-regex="CN=(.*?)"
user-service-ref="myUserDetailsService" />
Log extract
09:42:24:214 DEBUG org.springframework.security.web.authentication.preauth.x509.SubjectDnX509PrincipalExtractor (SubjectDnX509PrincipalExtractor.java:43) - Subject DN is 'CN=rod, OU=Spring Security, O=Spring Framework'
09:42:24:218 DEBUG org.springframework.security.web.authentication.preauth.x509.SubjectDnX509PrincipalExtractor (SubjectDnX509PrincipalExtractor.java:58) - Extracted Principal name is ''
The subject-principal-regex you use is wrong. If you want the extracted principal to be rod for the DN in the log message, set the pattern to CN=(.*?), (note the comma at the end). Btw, I think it is the default pattern, so you might as well just skip this setting.
Element <security:x509 /> is used to enable X.509 authentication in spring security.
Attribute subject-principal-regex of element <security:x509 /> is used to provide a regular expression to extract user name out of client certificate.
Regular expression helps in customizing which part do we want to extract out of object of client certificate as our user, like first middle or what ever as specified in regular expression and I was getting null user because of invalid regular expression.
Further more, attribute subject-principal-regex is optional and if we don't provided it explicitly then corresponding class (SubjectDnX509PrincipalExtractor) constrtuctor provides it with following, by default regex "CN=(.*?)(?:,|$)"

Opening an SSL web-browser connection in HtmlUnit library

I've searched through web for couple hours on this issue, and none of the answers I found didn't really fit into my problem, so here's me, asking my first-ever question in SOF.
So, I'm trying to open a web-browser from a java program using the htmlunit library. The web site I need to connect requires SSL connection, and the certificate is stored in a USB key. Its iKey2023 product.
The system used to work(I did not write it), but one of the certificates in the USB key expired, so it automatically moved on to the next one (there were 4 certificates in total), and it suddenly stopped working.
It is giving me javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated error.
I'm back home now and I forgot the exact name of the method, but I remember the following.
Browser instance is created, using IE8
browser.setWebConnection method was called. This method, according to the API, is an internal API.
Make connection to the website by passing the URL as parameter
It's throwing the exception at step 3.
Some more details. The little details might be incorrect but I'm trying to describe a big picture.
At step 2, the method requites WebConnection object as a parameter, and there is a implementation of that interface. Within this implementation, a keystore is created using sun.security.pkcs11.SunPKCS11(configFileInputStream) (did I spell that correctly?)
It was sth like this.
Provider p = new sun.security.pkcs11.SunPKCS11(configFileInputStream);
Security.addProvider(p);
And create a keystore from this provider.
Using this keystore, within the WebConnection implementation, it creates a SSLSocket.
So, after the certificate has been switched to a new one, it's not picking up the certificate correctly.
Here's what I've tried.
I've tried to use different methods in the htmlunit library, something like setSecurityProvider, and I tried to put the Provider object created in above code snippet. I got class cast exception.
I tried to manually set the system properties(trustStore, trustStorePassword, keyStore, etc). In order to do this, I wanted to export the certificate out of the USB key, but it did not let me export the private key out from it, so I could not really create a valid PKCS12 file out of it (openSSL wanted a private key file along with .pem file for conversion, and I did not have that key file).
They did not work, and I'm so stuck right now.
I have a similar issue. In my case, an admin changed the certificate and I began encountering the same SSLPeerUnverifiedException.
I found that I can set the WebClient to use insecureSSL (prior to calling getPage())and I will no longer get the exception.
webClient.setUseInsecureSSL(true);
This however, doesn't resolve the issue as the server basically doesn't authenticate the client.
Its as if the WebClient is storing something that doesn't work with the new certificate.