seblucas / cops

Calibre OPDS (and HTML) PHP Server : web-based light alternative to Calibre content server / Calibre2OPDS to serve ebooks (epub, mobi, pdf, ...)
http://blog.slucas.fr/en/oss/calibre-opds-php-server
GNU General Public License v2.0
1.43k stars 229 forks source link

HTTP Error 404.11 – URL_DOUBLE_ESCAPED and security issues on IIS server #249

Closed horus68 closed 8 years ago

horus68 commented 8 years ago

IIS 7.x server do not allow + signs in URL (or Double escape sequences) giving you a HTTP Error 404.11 – URL_DOUBLE_ESCAPED when downloading a book named as "Born to Run - Mercedes Lackey.epub" The link would be download/242/Born+to+Run+-+Mercedes+Lackey.epub

See official info: Error message when you visit a Web site that is hosted on IIS 7.0: "HTTP Error 404.11 – URL_DOUBLE_ESCAPED" - https://support.microsoft.com/en-gb/kb/942076

I try to include the rule to allow URL_DOUBLE_ESCAPED in my web.config (I am on a shared host, no access to server level)

    <security>
      <requestFiltering allowDoubleEscaping="true" />
    </security>

But this caused the server to fire a "404 error not found" when downloading books

$config['cops_use_url_rewriting'] = "0";

So now it works... but

So this is a big mess!

Question is:

Note that allowing Double escape sequences is a security issue: Another IIS Blog - IIS7 rejecting URLs containing + - http://blogs.iis.net/thomad/iis7-rejecting-urls-containin

horus68 commented 8 years ago

Update: this comment was for a related issue and it is now into a new issue https://github.com/seblucas/cops/issues/253

seblucas commented 8 years ago

Hi,

You've discovered two interesting problems. First one (url rewriting with IIS), it should be enough to modify the method getHtmlLinkWithRewriting in data.php to replace urlencode by rawurlencode in this snippet :

        if ($config['cops_provide_kepub'] == "1" &&
            $this->isEpubValidOnKobo () &&
            preg_match("/Kobo/", $_SERVER['HTTP_USER_AGENT'])) {
            $href .= urlencode ($this->getUpdatedFilenameKepub ());
        } else {
            $href .= urlencode ($this->getFilename ());
        }

EDIT : I've edited my proposition

seblucas commented 8 years ago

About your other problem, which browser are you using ?

seblucas commented 8 years ago

If you manage to test my previous change, don't bother to start a PR, there's a lot of unit test to change (I've already done it locally).

seblucas commented 8 years ago

Commit done 2bd02496fe64cf1d1ebbaa2f7ca2cc0b3afddf18

horus68 commented 8 years ago

the solution is not working for me. Tested under Firefox and Chrome latest versions The actual file can be read fine with epub preview or downloaded ok when URL rewrite is disabled

2016-02-16 10_16_47-caio fernando abreu

to implement your fix: changed the IF in urlencode to rawurlencode data.php file:

        if ($config['cops_provide_kepub'] == "1" &&
            $this->isEpubValidOnKobo () &&
            preg_match("/Kobo/", $_SERVER['HTTP_USER_AGENT'])) {
            $href .= rawurlencode ($this->getUpdatedFilenameKepub ());
        } else {
            $href .= urlencode ($this->getFilename ());
        }

and config_local.php goes like this

   $config['cops_use_url_rewriting'] = "1";
   $config['cops_provide_kepub'] = "1";

it fires a HTTP Error 404.11 - Not Found and the URL is ../download/156/Os+dragoes+nao+conhecem+o+parai+-+Caio+Fernando+Abreu.epub

Requested URL
.. :80/download/156/Os+dragoes+nao+conhecem+o+parai+-+Caio+Fernando+Abreu.epub Physical Path C:\inetpub\wwwroot\download\156\Os+dragoes+nao+conhecem+o+parai+-+Caio+Fernando+Abreu.epub

2016-02-16 10_51_01-iis 8 5 detailed error - 404 11 - not found

Also: if I change both IF and ELSE urlencode to rawurlencode in data.php file: I get a 404 error for the URL: ../download/156/Os%20dragoes%20nao%20conhecem%20o%20parai%20-%20Caio%20Fernando%20Abreu.epub

2016-02-16 10_56_04-404 - file or directory not found

seblucas commented 8 years ago

Just to be sure did you replace both urlencode by rawurlencode ?

horus68 commented 8 years ago

yes, double time confirmed! Then it gave the error 404 described in the end of the last reply

seblucas commented 8 years ago

OK, I think I may have forgot to use my brain before coding ....

How did you configure IIS for the URL rewriting ? COPS installation package does nothing by itself ! IIRC I tried to configure it at work and I needed to install a specific package, I'll check if I can find it.

seblucas commented 8 years ago

Hi, here is the web.config I tested :

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <staticContent>
            <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="14.00:00:00" />
        </staticContent>
        <rewrite>
            <rules>
                <rule name="Download with db" stopProcessing="true">
                    <match url="download/(\d*)/(\d*)/.*\.(.*?)$" />
                    <action type="Rewrite" url="fetch.php?data={R:1}&amp;db={R:2}&amp;type={R:3}" appendQueryString="false" />
                </rule>
                <rule name="Download without db" stopProcessing="true">
                    <match url="download/(\d*)/.*\.(.*?)$" />
                    <action type="Rewrite" url="fetch.php?data={R:1}&amp;type={R:2}" appendQueryString="false" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>

Seems to work fine. You also need to install the rewrite extension.

horus68 commented 8 years ago

With your fix for web.config download now works fine with URL rewrite. It works fine with Kobo too! Should we updated the wiki or will this fix be a standard in new version?

The second issue is still on ( strange letters if $config['cops_update_epub-metadata'] = "1"; ) but I will open a new issue to make this simpler to follow!

seblucas commented 8 years ago

Thanks for the confirmation (I've committed an updated web.config), I guess updating this wiki page could help at least to confirm it's supported.