Uploaded image for project: 'XWiki Platform'
  1. XWiki Platform
  2. XWIKI-25747

PasswordClass throws a shared static exception whose stack trace points to XWiki initialization instead of the actual caller

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • Major
    • None
    • 18.4.5, 18.8.0-rc-1, 17.10.14
    • Old Core
    • None
    • Unknown

    Description

      PasswordClass creates the IllegalArgumentException it throws for an unknown encoded password format once, in a static field, instead of where the error happens:

      private static final IllegalArgumentException ILLEGAL_ARGUMENT_EXCEPTION_UNKNOWN_FORMAT =
          new IllegalArgumentException("The provided encoded password doesn't match any known hash "
              + "encoded password format.");
      

      That same instance is then thrown by getAlgorithmFromPassword(String) and arePasswordsMatching(String, String). A Java exception's stack trace is captured when it is constructed, so every log of this error shows the stack of whatever first loaded PasswordClass, typically the XWiki initialization thread, and never the code that actually passed the unknown password value.

      Example

      The OIDC provider's userinfo endpoint failing on an XWiki 17.10.15 instance logs:

      [http-nio-8080-exec-10 - http://intra.example.org/xwiki/oidc/userinfo] DEBUG i.OIDCResourceReferenceHandler - Failed to handle the OIDC endpoint
      java.lang.IllegalArgumentException: The provided encoded password doesn't match any known hash encoded password format.
      	at com.xpn.xwiki.objects.classes.PasswordClass.<clinit>(PasswordClass.java:207)
      	at com.xpn.xwiki.objects.meta.PasswordMetaClass.getInstance(PasswordMetaClass.java:103)
      	at com.xpn.xwiki.internal.filter.output.PropertyClassOutputFilterStream.beginWikiClassProperty(PropertyClassOutputFilterStream.java:109)
      	...
      	at com.xpn.xwiki.store.XWikiHibernateStore.loadXWikiDoc(XWikiHibernateStore.java:1117)
      	...
      	at com.xpn.xwiki.XWiki.initializeMandatoryDocuments(XWiki.java:1412)
      	at com.xpn.xwiki.XWiki.initXWiki(XWiki.java:1340)
      	...
      	at com.xpn.xwiki.internal.XWikiInitializerJob.runInternal(XWikiInitializerJob.java:103)
      

      The request runs on an HTTP thread, but the logged stack is the startup one. It suggests that PasswordClass failed to initialize, while the exception was in fact thrown much later, from arePasswordsMatching called through the OIDC consent store's access token check. Finding the real caller requires reading the code, and there is no way to know which stored value or which document is involved.

      Expected

      A new exception is created at each throw, so that its stack trace shows the actual caller. Ideally its message also gives some context, for example the location of the property, when known, but never the password value itself.

      A shared, mutable exception instance has other drawbacks: any code calling addSuppressed or initCause on it (try-with-resources, wrapping) modifies the one instance used by every thread for the lifetime of the JVM.

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              tmortagne Thomas Mortagne
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

                Created:
                Updated: