Redirection Between HTTP URL and HTTPS URL Is Not Followed

Symptoms

When running an applet in a browser using the Sun Java Runtime Environment (JRE), if the applet makes HTTP requests to a server that redirects the request to an HTTPS URL, the redirection fails. The redirection also fails in the case of making HTTPS requests to a server that redirects the request to an HTTP URL. The same applet runs without any error in the Microsoft Virtual Machine (VM).

Cause

The issue is caused by the HTTP or HTTPS redirection policy implemented in Sun JRE. Because of serious security consequences, redirection between HTTP and HTTPS is not automatically followed.

When an applet is run in a browser using the Microsoft VM, a security warning dialog prompts the user for his consent to redirect. Redirection fails if the user does not consent to it.

Resolution

The application which runs the applet in a browser needs to check the response code and recognize it as a redirect. The Location header field value can be checked for the redirect information, and then the application must decide whether or not to follow the redirect using the new protocol. For example, if the following code is available in an application:

public void makeConnection(URL url)
{
URLConnection conn = url.openConnection();
InputStream is = conn.getInputStream();
....
is.close();
}

the above code should be changed to the following code:

private InputStream openConnectionCheckRedirects(URLConnection c) throws IOException
{

   boolean redir;
   int redirects = 0;
   InputStream in = null;
   do
   {
      if (c instanceof HttpURLConnection)

      {
         ((HttpURLConnection) c).setInstanceFollowRedirects(false);
      }
      // We want to open the input stream before getting headers
      // because getHeaderField() et al swallow IOExceptions.
      in = c.getInputStream();
      redir = false;
      if (c instanceof HttpURLConnection)
      {
         HttpURLConnection http = (HttpURLConnection) c;
         int stat = http.getResponseCode();
         if (stat >= 300 && stat <= 307 && stat != 306 &&
            stat != HttpURLConnection.HTTP_NOT_MODIFIED)
         {
            URL base = http.getURL();
            String loc = http.getHeaderField("Location");
            URL target = null;
            if (loc != null)
            {
               target = new URL(base, loc);
            }
            http.disconnect();
        
   // Redirection should be allowed only for HTTP and HTTPS
            // and should be limited to 5 redirections at most.
            if (target == null || !(target.getProtocol().equals("http")
               || target.getProtocol().equals("https"))
               || redirects >= 5)
            {

               throw new SecurityException("illegal URL redirect");
            }

            redir = true;
            c = target.openConnection();
            redirects++;
         }
      }
   }
   while (redir);
   return in;
}

public void makeConnection(URL url){
try{
   URLConnection conn = url.openConnection();
   InputStream is = openConnectionCheckRedirects(conn);
   ....
   is.close();
}catch (IOException e){ } }

Related Information

None.

 


Copyright © 1993, 2011, Oracle and/or its affiliates. All rights reserved.