]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/WwwAttach.pm
treewide: replace {-inbox} with {ibx} for consistency
[public-inbox.git] / lib / PublicInbox / WwwAttach.pm
index 0b2cda900ea00be6c181c288f3a5379f82588d87..0fe63e4232510a4facb9d2fe724c3fbd23af1bc3 100644 (file)
@@ -9,6 +9,22 @@ use bytes (); # only for bytes::length
 use PublicInbox::EmlContentFoo qw(parse_content_type);
 use PublicInbox::Eml;
 
+sub referer_match ($) {
+       my ($ctx) = @_;
+       my $env = $ctx->{env};
+       my $referer = $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'} . '://' .
+                       ($env->{HTTP_HOST} //
+                        "$env->{SERVER_NAME}:$env->{SERVER_PORT}") . '/';
+       index($referer, $base_url) == 0;
+}
+
 sub get_attach_i { # ->each_part callback
        my ($part, $depth, $idx) = @{$_[0]};
        my $ctx = $_[1];
@@ -28,8 +44,14 @@ sub get_attach_i { # ->each_part callback
                                                                $ctx->{env});
                $part = $ctx->zflush($part->body);
        } else { # TODO: allow user to configure safe types
-               $res->[1]->[1] = 'application/octet-stream';
-               $part = $part->body;
+               if (referer_match($ctx)) {
+                       $res->[1]->[1] = 'application/octet-stream';
+                       $part = $part->body;
+               } else {
+                       $res->[0] = 403;
+                       $res->[1]->[1] = 'text/plain';
+                       $part = "Deep-linking prevented\n";
+               }
        }
        push @{$res->[1]}, 'Content-Length', bytes::length($part);
        $res->[2]->[0] = $part;
@@ -66,15 +88,15 @@ sub get_attach ($$$) {
        $ctx->{idx} = $idx;
        bless $ctx, __PACKAGE__;
        my $eml;
-       if ($ctx->{smsg} = $ctx->{-inbox}->smsg_by_mid($ctx->{mid})) {
+       if ($ctx->{smsg} = $ctx->{ibx}->smsg_by_mid($ctx->{mid})) {
                return sub { # public-inbox-httpd-only
                        $ctx->{wcb} = $_[0];
                        scan_attach($ctx);
                } if $ctx->{env}->{'pi-httpd.async'};
                # generic PSGI:
-               $eml = $ctx->{-inbox}->smsg_eml($ctx->{smsg});
-       } elsif (!$ctx->{-inbox}->over) {
-               if (my $bref = $ctx->{-inbox}->msg_by_mid($ctx->{mid})) {
+               $eml = $ctx->{ibx}->smsg_eml($ctx->{smsg});
+       } elsif (!$ctx->{ibx}->over) {
+               if (my $bref = $ctx->{ibx}->msg_by_mid($ctx->{mid})) {
                        $eml = PublicInbox::Eml->new($bref);
                }
        }