MyFaces Core
  1. MyFaces Core
  2. MYFACES-1838

javax.crypto.BadPaddingException: Given final block not properly padded

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.2.2
    • Fix Version/s: 1.2.9
    • Component/s: None
    • Labels:
      None

      Description

      I keep getting this exception from time to time when moving between pages:

      javax.faces.FacesException: javax.crypto.BadPaddingException: Given final block not properly padded
      at org.apache.myfaces.shared_impl.util.StateUtils.symmetric(StateUtils.java:373)
      at org.apache.myfaces.shared_impl.util.StateUtils.symmetric(StateUtils.java:411)
      at org.apache.myfaces.shared_impl.util.StateUtils.decrypt(StateUtils.java:291)
      at org.apache.myfaces.shared_impl.util.StateUtils.reconstruct(StateUtils.java:240)
      at org.apache.myfaces.renderkit.html.HtmlResponseStateManager.getSavedState(HtmlResponseStateManager.java:184)
      at org.apache.myfaces.renderkit.html.HtmlResponseStateManager.getState(HtmlResponseStateManager.java:136)
      at org.apache.myfaces.application.jsp.JspStateManagerImpl.restoreView(JspStateManagerImpl.java:289)
      at org.apache.myfaces.application.jsp.JspViewHandlerImpl.restoreView(JspViewHandlerImpl.java:505)
      at org.apache.myfaces.lifecycle.RestoreViewExecutor.execute(RestoreViewExecutor.java:85)
      at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:103)
      at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:76)
      at javax.faces.webapp.FacesServlet.service(FacesServlet.java:148)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      at com.vdo.admin.model.persistence.OpenSessionInViewFilterIC.doFilterInternal(OpenSessionInViewFilterIC.java:155)
      at com.vdo.admin.model.persistence.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:61)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      at org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:147)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:263)
      at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
      at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:584)
      at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
      at java.lang.Thread.run(Thread.java:619)
      Caused by: javax.crypto.BadPaddingException: Given final block not properly padded
      at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
      at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
      at com.sun.crypto.provider.DESCipher.engineDoFinal(DashoA13*..)
      at javax.crypto.Cipher.doFinal(DashoA13*..)
      at org.apache.myfaces.shared_impl.util.StateUtils.symmetric(StateUtils.java:369)
      ... 30 more

        Issue Links

          Activity

          Hide
          Leonardo Uribe added a comment -

          Now a ViewExpiredException is thrown instead this one, but the detail about it is logged. If no secret is set a random key is generated. If the server is restarted a different key is used to encrypt/decrypt, so that's the cause of the exception. The exception in this case is expected.

          Show
          Leonardo Uribe added a comment - Now a ViewExpiredException is thrown instead this one, but the detail about it is logged. If no secret is set a random key is generated. If the server is restarted a different key is used to encrypt/decrypt, so that's the cause of the exception. The exception in this case is expected.
          Hide
          Michael Heinen added a comment -

          I had to turn it off (org.apache.myfaces.USE_ENCRYPTION=false) because this exception occurred randomly during jMeter performance tests. I could not see any pattern, sometimes the requests were fine and sometimes this exception occurs.

          Show
          Michael Heinen added a comment - I had to turn it off (org.apache.myfaces.USE_ENCRYPTION=false) because this exception occurred randomly during jMeter performance tests. I could not see any pattern, sometimes the requests were fine and sometimes this exception occurs.
          Hide
          Michal Borowiecki added a comment -

          We added org.apache.myfaces.SECRET context-param but we are still getting this exception after redeployment.
          myfaces 1.2.8, default algorithm, secret size of 8, base64 encoded using StateUtils, as described in http://wiki.apache.org/myfaces/Secure_Your_Application

          Any ideas?

          Show
          Michal Borowiecki added a comment - We added org.apache.myfaces.SECRET context-param but we are still getting this exception after redeployment. myfaces 1.2.8, default algorithm, secret size of 8, base64 encoded using StateUtils, as described in http://wiki.apache.org/myfaces/Secure_Your_Application Any ideas?
          Hide
          Mike Kienenberger added a comment -

          I suspect this bug can be caused by corrupted or truncated form submissions.

          Here's some related situations I've seen in the past:

          1) An apache proxy server that truncates form submissions at 4K, resulting in a truncated view state value sent back to the server.

          2) An Oracle application server that inexplicably sends a truncated page back to the client, resulting in a corrupted encrypted view state value on the client's web page, which eventually gets sent back to the server.

          For 2) You can examine the page submitting the failed request and determine if the page is corrupted.

          For 1) You'll have to do some testing to see if there's an artificial limit on form submissions being enforced on your submitted form data. I wrote a simple servlet to check what was received after submission. I suppose a servlet filter could do the same thing.

          Note than none of these issues are specific to JSF.

          Show
          Mike Kienenberger added a comment - I suspect this bug can be caused by corrupted or truncated form submissions. Here's some related situations I've seen in the past: 1) An apache proxy server that truncates form submissions at 4K, resulting in a truncated view state value sent back to the server. 2) An Oracle application server that inexplicably sends a truncated page back to the client, resulting in a corrupted encrypted view state value on the client's web page, which eventually gets sent back to the server. For 2) You can examine the page submitting the failed request and determine if the page is corrupted. For 1) You'll have to do some testing to see if there's an artificial limit on form submissions being enforced on your submitted form data. I wrote a simple servlet to check what was received after submission. I suppose a servlet filter could do the same thing. Note than none of these issues are specific to JSF.
          Hide
          Helmut Swaczinna added a comment -

          Hi Simon,

          this doesn't help at all:

          (3) use server-side state saving (only client-side state is encrypted)

          because the encrypted view id is still stored on the client-side.

          btw, I recognized this problem so far only with IE 6/7. Why this?

          Regards
          Helmut

          Show
          Helmut Swaczinna added a comment - Hi Simon, this doesn't help at all: (3) use server-side state saving (only client-side state is encrypted) because the encrypted view id is still stored on the client-side. btw, I recognized this problem so far only with IE 6/7. Why this? Regards Helmut
          Hide
          Felix Becker added a comment - - edited

          Hi Simon,

          i already tried the steps - disabling the encryption helps. The encryption handling should really be fixed.

          also the sides work perfect a long time before they crash permanently with this error - this doesn't look like a configuration error.

          if something (which causes this error) changes at the client, the server should be able to handle this.

          Is there a security risk when the encryption is disabled and the state is saved on the server instead of the client?

          regards

          felix

          Show
          Felix Becker added a comment - - edited Hi Simon, i already tried the steps - disabling the encryption helps. The encryption handling should really be fixed. also the sides work perfect a long time before they crash permanently with this error - this doesn't look like a configuration error. if something (which causes this error) changes at the client, the server should be able to handle this. Is there a security risk when the encryption is disabled and the state is saved on the server instead of the client? regards felix
          Hide
          Simon Kitching added a comment -

          I don't believe this is a bug at all. Unless I've misunderstood something, it's just missing configuration.

          I think any of the following (in order of preference) should solve this:

          (1) in web.xml, define init-parameter "org.apache.myfaces.SECRET" to be some reasonably long string. The server will then use the same encryption secret after restart (instead of generating a key itself), and so will be able to decrypt "old" sessions.

          (2) in web.xml, define init-parameter "org.apache.myfaces.USE_ENCRYPTION" to be "false", in order to disable client-side state encryption. Of course this potentially opens a security hole in the app.

          (3) use server-side state saving (only client-side state is encrypted)

          Show
          Simon Kitching added a comment - I don't believe this is a bug at all. Unless I've misunderstood something, it's just missing configuration. I think any of the following (in order of preference) should solve this: (1) in web.xml, define init-parameter "org.apache.myfaces.SECRET" to be some reasonably long string. The server will then use the same encryption secret after restart (instead of generating a key itself), and so will be able to decrypt "old" sessions. (2) in web.xml, define init-parameter "org.apache.myfaces.USE_ENCRYPTION" to be "false", in order to disable client-side state encryption. Of course this potentially opens a security hole in the app. (3) use server-side state saving (only client-side state is encrypted)
          Hide
          Felix Becker added a comment - - edited

          when will this bug be fixed? it is really critical because it suddenly occurs in productive environments and it is not repairable with restarting the server!

          MyFaces Core 1.2.5 is affected, too!

          Show
          Felix Becker added a comment - - edited when will this bug be fixed? it is really critical because it suddenly occurs in productive environments and it is not repairable with restarting the server! MyFaces Core 1.2.5 is affected, too!
          Hide
          Keywan added a comment -

          Thank you, I was ask to provide my full workaround for the patched version,
          for the unpatched version it would be quite similar but don't hesitate to ask me:

          The workaround with my ServletExceptionHandler works fine in combination with the errorpage from my last preceding post.

          //use for free but without warantie
          public class ServletExceptionHandler {

          public void handle(PageContext context,String nicePage)

          { Throwable ex = context.getErrorData().getThrowable(); handle(context,ex, nicePage); }

          public void handle(PageContext context,Throwable ex,String nicePage){

          //try

          if (ex instanceof ViewExpiredException){
          if (context.getResponse() instanceof HttpServletResponse )

          { HttpServletResponse x = (HttpServletResponse) context.getResponse(); x.sendRedirect(context.getErrorData().getRequestURI()); return; }

          }
          //...
          //lot of more code but its not yet open source
          // informe someone about the error
          //and forward the user to an jsf page to informe him too.
          }

          Show
          Keywan added a comment - Thank you, I was ask to provide my full workaround for the patched version, for the unpatched version it would be quite similar but don't hesitate to ask me: The workaround with my ServletExceptionHandler works fine in combination with the errorpage from my last preceding post. //use for free but without warantie public class ServletExceptionHandler { public void handle(PageContext context,String nicePage) { Throwable ex = context.getErrorData().getThrowable(); handle(context,ex, nicePage); } public void handle(PageContext context,Throwable ex,String nicePage){ //try if (ex instanceof ViewExpiredException){ if (context.getResponse() instanceof HttpServletResponse ) { HttpServletResponse x = (HttpServletResponse) context.getResponse(); x.sendRedirect(context.getErrorData().getRequestURI()); return; } } //... //lot of more code but its not yet open source // informe someone about the error //and forward the user to an jsf page to informe him too. }
          Hide
          Michael Concini added a comment - - edited

          For your todo section in your patch, you could probably do something like this to filter out only the BadPaddingExceptions and then rethrow anything else:

          if (e.getCause().getClass().equals((new javax.crypto.BadPaddingException()).getClass()))

          { return null; }

          else

          { throw e; }

          There's probably a more elegant way of doing that, but this does work. I had been testing out a similar fix in my environment for the same problem.

          I agree it would be nice if myfaces would handle the ViewExpired and create a new view after logging a message, but at least with your fix the error thrown will more likely lead the user to the actual problem.

          Show
          Michael Concini added a comment - - edited For your todo section in your patch, you could probably do something like this to filter out only the BadPaddingExceptions and then rethrow anything else: if (e.getCause().getClass().equals((new javax.crypto.BadPaddingException()).getClass())) { return null; } else { throw e; } There's probably a more elegant way of doing that, but this does work. I had been testing out a similar fix in my environment for the same problem. I agree it would be nice if myfaces would handle the ViewExpired and create a new view after logging a message, but at least with your fix the error thrown will more likely lead the user to the actual problem.
          Hide
          Keywan added a comment - - edited

          The patch catches the exception and returng null in the HtmlResponseStateManager, but this will result in an javax.faces.application.ViewExpiredException.
          I would like myfaces to create a facesmassage, create a new state and display the site, so the user is infored that he have to refill the form, but the user should be able to proceed.

          For know i will try a workaround :
          handel the exception at my error page. There i can get the reason and if it is an javax.faces.application.ViewExpiredException, i will give a message and redirect to the orgin page.

          For those who haven't yet my patch build in, also can create a errorpage to catach the badpadding exception:
          in web.xml you can set an error page but dont forgett to disable facelets or/and mayfaces errorpages
          <context-param>
          <param-name>org.apache.myfaces.ERROR_HANDLING</param-name>
          <param-value>false</param-value>
          </context-param>
          <context-param>
          <param-name>facelets.DEVELOPMENT</param-name>
          <param-value>false</param-value>
          </context-param>
          <error-page>
          <exception-type>javax.servlet.ServletException</exception-type>
          <location>/error.jsp</location>
          </error-page>

          the error page must handle, the exceptionen, hopefully that some day we can register a Exceptionhandler, i siply call my Exceptionhandler at this page. But u can remove this lines and try to add a workaround .

          <!doctype html public "-//w3c//dtd html 4.0 transitional//en">
          <%@page import="com.ibson.errorhandling.ServletExceptionHandler"%>
          <%@page isErrorPage="true" %>
          <html>
          <head></head>
          <body>
          <%
          ServletExceptionHandler handler = new ServletExceptionHandler();
          handler.handle(pageContext,"/pages/error.jsf");
          %>
          </body>
          </html>

          Show
          Keywan added a comment - - edited The patch catches the exception and returng null in the HtmlResponseStateManager, but this will result in an javax.faces.application.ViewExpiredException. I would like myfaces to create a facesmassage, create a new state and display the site, so the user is infored that he have to refill the form, but the user should be able to proceed. For know i will try a workaround : handel the exception at my error page. There i can get the reason and if it is an javax.faces.application.ViewExpiredException, i will give a message and redirect to the orgin page. For those who haven't yet my patch build in, also can create a errorpage to catach the badpadding exception: in web.xml you can set an error page but dont forgett to disable facelets or/and mayfaces errorpages <context-param> <param-name>org.apache.myfaces.ERROR_HANDLING</param-name> <param-value>false</param-value> </context-param> <context-param> <param-name>facelets.DEVELOPMENT</param-name> <param-value>false</param-value> </context-param> <error-page> <exception-type>javax.servlet.ServletException</exception-type> <location>/error.jsp</location> </error-page> the error page must handle, the exceptionen, hopefully that some day we can register a Exceptionhandler, i siply call my Exceptionhandler at this page. But u can remove this lines and try to add a workaround . <!doctype html public "-//w3c//dtd html 4.0 transitional//en"> <%@page import="com.ibson.errorhandling.ServletExceptionHandler"%> <%@page isErrorPage="true" %> <html> <head></head> <body> <% ServletExceptionHandler handler = new ServletExceptionHandler(); handler.handle(pageContext,"/pages/error.jsf"); %> </body> </html>
          Hide
          Baroch Oren added a comment -

          I have no knowledge as to how to bypass this issue.
          I've made a former attempt to catch it using a filter (servlet), but it would not propagate out of MyFaces. So it appears as something that should be addressed in MyFaces code.

          If there's any idea or a workaround, please comment.

          Show
          Baroch Oren added a comment - I have no knowledge as to how to bypass this issue. I've made a former attempt to catch it using a filter (servlet), but it would not propagate out of MyFaces. So it appears as something that should be addressed in MyFaces code. If there's any idea or a workaround, please comment.
          Hide
          Greg Lloyd added a comment -

          Is there any work around for this, maybe by disabling the encryption of the state etc?

          Show
          Greg Lloyd added a comment - Is there any work around for this, maybe by disabling the encryption of the state etc?
          Hide
          Keywan added a comment -

          Background: the client sends a encryptet state id to the server, and the server try to decode it with a private key.

          But when the server is restartet the private key changes and the decrypting fails.

          Maybe the BadPaddingException can be caught in org.apache.myfaces.renderkit.html.HtmlResponseStateManager.getSavedState
          in Line 184
          @version $Revision: 596453 $ $Date: 2007-11-19 16:22:37 -0500 (Mon, 19 Nov 2007) $

          and just return null for the state when the exception is caught.

          Show
          Keywan added a comment - Background: the client sends a encryptet state id to the server, and the server try to decode it with a private key. But when the server is restartet the private key changes and the decrypting fails. Maybe the BadPaddingException can be caught in org.apache.myfaces.renderkit.html.HtmlResponseStateManager.getSavedState in Line 184 @version $Revision: 596453 $ $Date: 2007-11-19 16:22:37 -0500 (Mon, 19 Nov 2007) $ and just return null for the state when the exception is caught.
          Hide
          Baroch Oren added a comment -

          I get this exception sometimes as I restart the web container (jetty). Can't say what causes it since the behavior appears to occur randomly.
          My environment:
          Spring 2.0.5 - MyFaces Core 1.2.2 - Tomahawk 1.16 - RichFaces 3.2.0 SR1 - Facelets 1.1.14 - Jetty 6.1.2
          I'm browsing with IceWeasel 2.0.0.14 - Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.14) Gecko/20080404 Iceweasel/2.0.0.14 (Debian-2.0.0.14-0etch1)

          Would love to add any other info needed to reproduce.

          Show
          Baroch Oren added a comment - I get this exception sometimes as I restart the web container (jetty). Can't say what causes it since the behavior appears to occur randomly. My environment: Spring 2.0.5 - MyFaces Core 1.2.2 - Tomahawk 1.16 - RichFaces 3.2.0 SR1 - Facelets 1.1.14 - Jetty 6.1.2 I'm browsing with IceWeasel 2.0.0.14 - Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.14) Gecko/20080404 Iceweasel/2.0.0.14 (Debian-2.0.0.14-0etch1) Would love to add any other info needed to reproduce.

            People

            • Assignee:
              Leonardo Uribe
              Reporter:
              Guy Bashan
            • Votes:
              17 Vote for this issue
              Watchers:
              14 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development