benlucchesi / grails-cookie-session

cookie sessions for grails applications
28 stars 32 forks source link

Bad character in base64 value #63

Open tushar-saxena opened 8 years ago

tushar-saxena commented 8 years ago

Hi benlucchesi, I am using cookie session plugin. but i found that sometimes it fails while deserializing session. The stacktrace is given below.

2015-10-21 15:14:37,407 [http-bio-8080-exec-576] ERROR cookiesession.CookieSessionRepository - An error occurred while deserializing a session. java.lang.RuntimeException: bad character in base64 value at org.codehaus.groovy.runtime.EncodingGroovyMethods.decodeBase64(EncodingGroovyMethods.java:177) at org.codehaus.groovy.runtime.dgm$661.invoke(Unknown Source) at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:271) at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:53) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112) at com.granicus.grails.plugins.cookiesession.CookieSessionRepository.deserializeSession(CookieSessionRepository.groovy:410) at com.granicus.grails.plugins.cookiesession.CookieSessionRepository$deserializeSession$16.callCurrent(Unknown Source) at com.granicus.grails.plugins.cookiesession.CookieSessionRepository.restoreSession(CookieSessionRepository.groovy:314) at com.granicus.grails.plugins.cookiesession.SessionRepositoryRequestWrapper.restoreSession(SessionRepositoryRequestWrapper.java:58) at com.granicus.grails.plugins.cookiesession.CookieSessionFilter.doFilterInternal(CookieSessionFilter.java:74) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344) at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.codehaus.groovy.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:67) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at javax.servlet.FilterChain$doFilter$4.call(Unknown Source) at com.brandseye.cors.CorsFilter.doFilterInternal(CorsFilter.groovy:32) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344) at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:957) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:620) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:745)

tushar-saxena commented 8 years ago

Just for you reference EncodingGroovyMethodsSupport.TRANSLATE_TABLE it returns value 66 for serialized session

%22D%2BUT8uHIi9xDqWHb5f91RWmQdt2HJ3c0RH%2FrHb%2FS8nsE1jD7h%2B0ATDbCLXjKWAri%2B%2FAIU1VViu71BPOXxyG%2BVpXUfGaUaHjT7e5PBkwrDBykzRR1wTD2GdA4mLT%2FKRJbKyxB200uO5tYVpc6tApy2xRiORjlh2b9q4Q4qZL2yjGh2Wxe0Du8hNc9tyrbcf5ATarpWK1wzSgE2xYAwGIxHZsngY9LzIX1R2p60rIW9A9uwN72BN5KcnKy8q36eofkB%2FZD3f9EgMNNRbquyVK2BonUJIeUpbXP8Hahek3cBF7SiNR32PIEwoxlLFQ4IQtWtxYOyjOGposw2RKhz3mxojFMek2Hx4JFmbgYOe4Bd7N1UtNmpJQSvg%3D%3D%22

so sixBit is setting to 66

else if (sixBit == 66) { // RFC 2045 says that I'm allowed to take the presence of // these characters as evidence of data corruption // So I will throw new RuntimeException("bad character in base64 value"); // TODO: change this exception type }

then this code throws exception.

benlucchesi commented 8 years ago

Hi Tushar,

I doubt the base64 encoding and decoding is the problem. Its more likely that that size of the serialized is exceeding the max size of allowable sessions and is getting truncated in such a way that a bad character is being formed in the base64 encoding.

I've seen the issue several times before and will include a strategy to dump malformed/truncated sessions in the event that they grow to large in a future release.

What version of the plugin are you using and what configuration settings have you made? I can look them over and make a recommendation if I see a problem. If you're using encryption, please don't share the cookiesession.secret for your production environment.

tushar-saxena commented 8 years ago

Hi benlucchesi,

I am using 2.0.17 version of cookie session plugin. And the configuration settings are given below.

grails.plugin.cookiesession.enabled = true grails.plugin.cookiesession.encryptcookie = true grails.plugin.cookiesession.cryptoalgorithm = "Blowfish" grails.plugin.cookiesession.secret = "mysecret" grails.plugin.cookiesession.cookiecount = 10 grails.plugin.cookiesession.maxcookiesize = 2048 // 2kb grails.plugin.cookiesession.sessiontimeout = 3600 // one hour grails.plugin.cookiesession.cookiename = 'gsession' grails.plugin.cookiesession.setsecure = false grails.plugin.cookiesession.serializer = 'kryo' grails.plugin.cookiesession.path = '/' grails.plugin.cookiesession.sethttponly = true grails.plugin.springsecurity.useSessionFixationPrevention = false