]> Sergey Matveev's repositories - public-inbox.git/commitdiff
www: loosen deep-linking prevention
authorEric Wong <e@80x24.org>
Tue, 15 Mar 2022 20:45:02 +0000 (20:45 +0000)
committerEric Wong <e@80x24.org>
Tue, 22 Mar 2022 08:32:24 +0000 (08:32 +0000)
Apparently some browsers can set a Referer: header which fails
to match.  I'm not certain why, but making "$schema://$HOST_PORT"
matches case-insensitive seems more correct regardless.

In case that doesn't work, we'll also allow bypassing deep-link
prevention via a POST form button.

Reported-by: Vlastimil Babka <vbabka@suse.cz>
Link: https://public-inbox.org/meta/93ebfbd1-9924-481c-4edc-9b232d1e995c@suse.cz/
lib/PublicInbox/WWW.pm
lib/PublicInbox/WwwAttach.pm

index a282784a257fb523ca3ae6a59567628709ecd5a6..755d75585df22a18ab495d844705fd075cf57f45 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2014-2021 all contributors <meta@public-inbox.org>
+# Copyright (C) all contributors <meta@public-inbox.org>
 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
 #
 # Main web interface for mailing list archives
@@ -64,6 +64,10 @@ sub call {
                                serve_git($ctx, $epoch, $path);
                } elsif ($path_info =~ m!$INBOX_RE/(\w+)\.sql\.gz\z!o) {
                        return get_altid_dump($ctx, $1, $2);
+               } elsif ($path_info =~ m!$INBOX_RE/$MID_RE/$ATTACH_RE\z!o) {
+                       my ($idx, $fn) = ($3, $4);
+                       return invalid_inbox_mid($ctx, $1, $2) ||
+                               get_attach($ctx, $idx, $fn);
                } elsif ($path_info =~ m!$INBOX_RE/!o) {
                        return invalid_inbox($ctx, $1) || mbox_results($ctx);
                }
index c17394afe8709b61caae9315f549d53c84ad758d..87844bf3f0e466a1b686f4e54eb0a9a6d5dd60ad 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2016-2021 all contributors <meta@public-inbox.org>
+# Copyright (C) all contributors <meta@public-inbox.org>
 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
 
 # For retrieving attachments from messages in the WWW interface
@@ -11,16 +11,17 @@ use PublicInbox::Eml;
 sub referer_match ($) {
        my ($ctx) = @_;
        my $env = $ctx->{env};
-       my $referer = $env->{HTTP_REFERER} // '';
+       return 1 if $env->{REQUEST_METHOD} eq 'POST';
+       my $referer = lc($env->{HTTP_REFERER} // '');
        return 1 if $referer eq ''; # no referer is always OK for wget/curl
 
        # prevent deep-linking from other domains on some browsers (Firefox)
        # n.b.: $ctx->{ibx}->base_url($env) with INBOX_URL won't work
        # with dillo, we can only match "$url_scheme://$HTTP_HOST/" without
        # path components
-       my $base_url = $env->{'psgi.url_scheme'} . '://' .
+       my $base_url = lc($env->{'psgi.url_scheme'} . '://' .
                        ($env->{HTTP_HOST} //
-                        "$env->{SERVER_NAME}:$env->{SERVER_PORT}") . '/';
+                        "$env->{SERVER_NAME}:$env->{SERVER_PORT}") . '/');
        index($referer, $base_url) == 0;
 }
 
@@ -46,8 +47,13 @@ sub get_attach_i { # ->each_part callback
                        $part = $part->body;
                } else {
                        $res->[0] = 403;
-                       $res->[1]->[1] = 'text/plain';
-                       $part = "Deep-linking prevented\n";
+                       $res->[1]->[1] = 'text/html';
+                       $part = <<"";
+<html><head><title>download
+attachment</title><body><pre>Deep-linking prevented</pre><form
+method=post\naction=""><input type=submit value="Download attachment"
+/></form></body></html>
+
                }
        }
        push @{$res->[1]}, 'Content-Length', length($part);