13 Replies Latest reply: Jun 4, 2013 8:42 PM by Capt. Egg RSS

    HttpOnly cookies impossible with mod_plsql?

    Capt. Egg
      I've noticed that OWA_COOKIE.SEND does not support the HttpOnly flag. So I attempted to achieve this manually by generating the "Set-Cookie" header. The problem is that something is sanitising my Set-Cookie header, no matter what I do.

      htp.init;
      htp.p('Set-Cookie: MY_COOKIE=TEST; HttpOnly');
      owa_util.http_header_close;
      htp.p('hi!');
      htp.flush;

      Results in...

      Set-Cookie: MY_COOKIE=TEST

      In the raw response header. This does not occur when I I execute the following PHP from the very same OHS...

      <?php
      header('Set-Cookie: MY_COOKIE=blah; HttpOnly');
      ?>

      Then I get...

      Set-Cookie: MY_COOKIE=blah; HttpOnly

      This lead me to believe the problem is in the htp.p procedure or perhaps mod_plsql. I trawled through the source for SYS.HTP package and could see no such Set-Cookie sanitisation code. This is why I suspect mod_plsql is responsible.

      Here's some version information...
      A 404 page of the OHS reports... Oracle-Application-Server-10g/10.1.3.1.0 Oracle-HTTP-Server

      select owa_util.get_version from dual;

      GET_VERSION
      -----------
      10.1.2.0.8

      Apache version 2.0 (bundled with OHS, don't know how to confirm exact version)

      Anyone know how to determine mod_plsql version??

      I've tried that block of PL/SQL both from an APEX page process and directly from a stored procedure. Both result in the trailing"; HttpOnly" being stripped. I've noticed that any change to the case of the letters in Set-Cookie is overridden and any other parameters other than expires, domain, path and secure are stripped out. There doesn't seem to be any way for me to force a raw Set-Cookie header without this sanitisation occurring.

      And here is the dads.conf entry...
      <Location /pls/apex>
      PlsqlErrorStyle DebugStyle
      Order deny,allow
      PlsqlDocumentPath docs
      AllowOverride None
      PlsqlDocumentProcedure wwv_flow_file_manager.process_download
      PlsqlDatabaseConnectString captain.egg.com:1521:ssdev ServiceNameFormat
      PlsqlNLSLanguage AMERICAN_AMERICA.AL32UTF8
      PlsqlAuthenticationMode Basic
      SetHandler pls_handler
      PlsqlDocumentTablename wwv_flow_file_objects$
      PlsqlDatabaseUsername APEX_PUBLIC_USER
      PlsqlDefaultPage apex
      PlsqlDatabasePassword NothingToSeeHere
      Allow from all
      </Location>

      Edited by: Capt. Egg on Jul 8, 2010 11:38 PM
      Added dads.conf
        • 1. Re: HttpOnly cookies impossible with mod_plsql?
          mseberg
          Change


          htp.init;
          htp.p('Set-Cookie: MY_COOKIE=TEST; HttpOnly');
          owa_util.http_header_close;
          htp.p('hi!');
          htp.flush;


          To





          htp.init;
          owa_util.mime_header('text/html', FALSE);
          htp.p('Set-Cookie: MY_COOKIE=TEST; HttpOnly');
          owa_util.http_header_close;
          htp.p('hi!');
          owa_util.http_header_close;
          htp.flush;
          • 2. Re: HttpOnly cookies impossible with mod_plsql?
            Capt. Egg
            Thanks, but the response header still doesn't contain HttpOnly when using that code.
            • 3. Re: HttpOnly cookies impossible with mod_plsql?
              Capt. Egg
              Still not working on APEX 4 on Oracle 11g R2.

              Apparently Fusion Middleware PL/SQL Web Toolkit supports httponly cookies...
              http://download.oracle.com/docs/cd/E14571_01/portal.1111/e12042/pscook.htm#i1005704

              How long before I can expect to see OWA get an upgrade in the database?
              • 4. Re: HttpOnly cookies impossible with mod_plsql?
                brian.mcginity
                I know this is an old post. I have the same problem. Found a soultion:

                Change owa_cookie package as:
                   procedure send(name    in varchar2,
                                  value   in varchar2,
                                  expires in date     DEFAULT NULL,
                                  path    in varchar2 DEFAULT NULL,
                                  domain  in varchar2 DEFAULT NULL,
                                  secure  in varchar2 DEFAULT NULL,
                                  httponly in varchar2 DEFAULT NULL) is
                ...
                ...
                ...
                
                                 IFNOTNULL(l_secure,  ' secure;') ||
                                 IFNOTNULL(httponly,  ' HttpOnly'));
                I have no idea why the manual say the httponly parameter is in cookie.send, when in fact it's not there. So might as well add it. Then add it to the cookie.send() invoke.
                • 5. Re: HttpOnly cookies impossible with mod_plsql?
                  933128
                  I want to know where you get the source code of the owa_cookie.send procedure? I can only get the header of this package from ...\RDBMS\ADMIN\pubcook.sql. Could you paste the whole source code here and then I can modify it to set the 'httponly' attribute? I also have a problem that after changing the package, how to use the package I changed? Does it still a system package here? Or it has been changed to an user-defined package in database and I need to execute the package on the database for the web server?
                  Thank you!
                  • 6. Re: HttpOnly cookies impossible with mod_plsql?
                    brian.mcginity
                    What I did was open Toad, login as Sys open the owa_cookie package and adjust it as folllows:
                       procedure send(name    in varchar2,
                                      value   in varchar2,
                                      expires in date     DEFAULT NULL,
                                      path    in varchar2 DEFAULT NULL,
                                      domain  in varchar2 DEFAULT NULL,
                                      secure  in varchar2 DEFAULT NULL,
                                      httponly in varchar2 DEFAULT NULL) is
                                      
                          expires_gmt date;
                          l_name      varchar2(32767);
                          l_value     varchar2(32767);
                          l_path      varchar2(32767);
                          l_domain    varchar2(32767);
                          l_secure    varchar2(32767);
                       begin
                          -- Validate parameters
                          l_name := validate_arg(name);
                          l_value := validate_arg(value);
                          l_path := validate_arg(path);
                          l_domain := validate_arg(domain);
                          l_secure := validate_arg(secure);
                    
                          if (OWA_CUSTOM.DBMS_SERVER_GMTDIFF is not NULL)
                          then
                             expires_gmt := expires-(OWA_CUSTOM.DBMS_SERVER_GMTDIFF/24);
                          else
                             expires_gmt := new_time(expires,OWA_CUSTOM.DBMS_SERVER_TIMEZONE,'GMT');
                          end if;
                    
                          -- When setting the cookie expiration header
                          -- we need to set the nls date language to AMERICAN
                          -- since the cookie line needs to be in English.
                          -- If the NLS_LANGUAGE of the database is other than
                          -- English, the expires tag is not understood by the browser.
                          htp.print('Set-Cookie: '||l_name||'='||l_value||';'||
                                     IFNOTNULL(expires_gmt, ' expires='||
                                        rtrim(to_char(expires_gmt,'Dy',
                                            'NLS_DATE_LANGUAGE = American'))||
                                        to_char
                                        (
                                            expires_gmt,
                                            ', DD-Mon-YYYY HH24:MI:SS',
                                            'NLS_DATE_LANGUAGE = American'
                                        )||' GMT;')||
                                     IFNOTNULL(l_path,    ' path='||l_path||';')||
                                     IFNOTNULL(l_domain,  ' domain='||l_domain||';')||
                                     IFNOTNULL(l_secure,  ' secure;') ||
                                     IFNOTNULL(httponly,  ' HttpOnly')
                                     );
                       end;
                    Then change the spec as well:
                       procedure send(name    in varchar2,
                                      value   in varchar2,
                                      expires in date     DEFAULT NULL,
                                      path    in varchar2 DEFAULT NULL,
                                      domain  in varchar2 DEFAULT NULL,
                                      secure  in varchar2 DEFAULT NULL,
                                      httponly in varchar2 DEFAULT NULL);
                    Compile it.
                    Then call it:
                     owa_util.mime_header (ccontent_type=>'text/html', bclose_header=>FALSE);     
                     owa_cookie.send (name=>'cookiename', value=>'xyz', path=>'/', expires=>'', secure=>'Y', httponly=>'Y');
                    • 7. Re: HttpOnly cookies impossible with mod_plsql?
                      brian.mcginity
                      Really it's not a good idea to modify code owned by sys. I did it becuase I was in a hurry. Since .send() only does htp.p calls, it would be better to write a custom cookie_send procedure in your own schema. I'll do it sooner or later.
                      • 8. Re: HttpOnly cookies impossible with mod_plsql?
                        933128
                        I create a package owa_cookie1 that use the code of the system owa_cookie. And add httponly parameter to it. And then call it as below.

                        owa_cookie1.send
                        (name => 'XXX',
                        value => cookie_value,
                        secure => 'Y',
                        httponly => 'Y'
                        );

                        I save the http header string 'Set-Cookie: XXX=123456789; secure; HttpOnly', but when I check the cookie on the client, the secure is true and httponly is false. It is very odd.

                        The version of my Oracle database is 10g. Is it the reason why the change did not work? What's your oracle version?

                        Edited by: Behrman Wu on 2012-4-27 上午8:01
                        • 9. Re: HttpOnly cookies impossible with mod_plsql?
                          brian.mcginity
                          How are you checking the cookie on the client? DB Version has nothing to do with it. If you wrote the cookie to the header the way the browser is expecting it, that's about all you can do. You might want to check with another tool or write some javascript which tries to get the cookie and see what happens.
                          • 10. Re: HttpOnly cookies impossible with mod_plsql?
                            brian.mcginity
                            The httpOnly flag is working for me. I just tested with this code:
                            CREATE OR REPLACE procedure cookie_test is
                            
                            begin
                            
                            htp.p('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><html  >
                            <head>
                              <title>test</title>
                            </head>
                            <body> 
                            
                            test
                            
                            <script>
                              function get_cookies_array() {
                                  var cookies = { };
                                  if (document.cookie && document.cookie != "") {
                                      var split = document.cookie.split(";");
                                      for (var i = 0; i < split.length; i++) {
                                          var name_value = split.split("=");
                            name_value[0] = name_value[0].replace(/^ /, "");
                            cookies[decodeURIComponent(name_value[0])] = decodeURIComponent(name_value[1]);
                            }
                            }

                            return cookies;
                            }

                            var cookies = get_cookies_array();
                            for(var name in cookies) {
                            document.write( name + " : " + cookies[name] + "<br />" );
                            }
                            </script>
                            </body>
                            </html>
                            ');
                            end;
                            /
                            When I create a cookie without httpOnly, the cookie is displayed with the above code.  When httpOnly is set, the cookie is not displayed.
                            
                            Edited by: brian.mcginity on Apr 27, 2012 3:54 PM                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
                            • 11. Re: HttpOnly cookies impossible with mod_plsql?
                              933128
                              The cookie we use is a session cookie so that we do not need give the expiry date. I use 'alert(document.cookie)' to show the info of cookie and it always show the info whatever I send the 'httponly' in the http header. I did not know where is wrong. It seems the 'httponly' word I added in the header string impact nothing in the cookie.
                              • 12. Re: HttpOnly cookies impossible with mod_plsql?
                                brian.mcginity
                                As an experiment, replace sys.owa_cookie.send with the one I’m using.
                                • 13. Re: HttpOnly cookies impossible with mod_plsql?
                                  Capt. Egg
                                  Thanks for the workaround. I've tested using cookies with OHS 11g (aka Web Tier on Oracle Fusion), it seems like all cookies are using HttpOnly by default.