Bug 15111 - Koha is vulnerable to Cross-Frame Scripting (XFS) attacks
authorKyle M Hall <kyle@bywatersolutions.com>
Mon, 2 Nov 2015 17:11:17 +0000 (12:11 -0500)
committerFrédéric Demians <f.demians@tamil.fr>
Wed, 27 Apr 2016 15:04:08 +0000 (17:04 +0200)
Web pages that can be embedded in frames are vulnerable to cross-frame
scripting attacks. Cross-frame scripting is a type of phishing attack
that involves instructions to an unsuspecting user to follow a specific
link to update confidential information in an online application.
Because the link leads to a legitimate page from the online application
that is embedded in a frame hosted by the attackers' server, the
attackers can capture all the information that the user enters.

https://www.owasp.org/index.php/Clickjacking_Defense_Cheat_Sheet
Signed-off-by: Chris Cormack <chrisc@catalyst.net.nz>

Signed-off-by: Katrin Fischer <katrin.fischer.83@web.de>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Chris Cormack <chrisc@catalyst.net.nz>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
(cherry picked from commit dc03bca76cf5b7cb48d98d1ce245fc65b98be929)
Signed-off-by: Julian Maurice <julian.maurice@biblibre.com>
(cherry picked from commit c97a01e1330ab5b1b1df7029d2149efa0deb19a4)
Signed-off-by: Frédéric Demians <f.demians@tamil.fr>

C4/Output.pm
koha-tmpl/intranet-tmpl/prog/en/includes/doc-head-close.inc
koha-tmpl/opac-tmpl/bootstrap/en/includes/doc-head-close.inc

index 1dbdbee..aa32b01 100644 (file)
@@ -253,11 +253,12 @@ sub output_with_http_headers {
     my $cache_policy = 'no-cache';
     $cache_policy .= ', no-store, max-age=0' if $extra_options->{force_no_caching};
     my $options = {
-        type    => $content_type_map{$content_type},
-        status  => $status,
-        charset => 'UTF-8',
-        Pragma          => 'no-cache',
-        'Cache-Control' => $cache_policy,
+        type              => $content_type_map{$content_type},
+        status            => $status,
+        charset           => 'UTF-8',
+        Pragma            => 'no-cache',
+        'Cache-Control'   => $cache_policy,
+        'X-Frame-Options' => 'DENY',
     };
     $options->{expires} = 'now' if $extra_options->{force_no_caching};
 
index 7662012..2a6f199 100644 (file)
@@ -1,4 +1,16 @@
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+[%# Prevent XFS attacks -%]
+<style id="antiClickjack">body{display:none !important;}</style>
+<script type="text/javascript">
+   if (self === top) {
+       var antiClickjack = document.getElementById("antiClickjack");
+       antiClickjack.parentNode.removeChild(antiClickjack);
+   } else {
+       top.location = self.location;
+   }
+</script>
+
 <link rel="shortcut icon" href="[% IF ( IntranetFavicon ) %][% IntranetFavicon %][% ELSE %][% interface %]/[% theme %]/img/favicon.ico[% END %]" type="image/x-icon" />
 <link rel="stylesheet" type="text/css" href="[% interface %]/lib/jquery/jquery-ui.css" />
 <link rel="stylesheet" type="text/css" href="[% interface %]/lib/bootstrap/bootstrap.min.css" />
index bce0da2..f9038f5 100644 (file)
@@ -1,6 +1,18 @@
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <meta name="generator" content="Koha [% Version %]" /> <!-- leave this for stats -->
 <meta name="viewport" content="width=device-width, initial-scale=1" />
+
+[%# Prevent XFS attacks -%]
+<style id="antiClickjack">body{display:none !important;}</style>
+<script type="text/javascript">
+   if (self === top) {
+       var antiClickjack = document.getElementById("antiClickjack");
+       antiClickjack.parentNode.removeChild(antiClickjack);
+   } else {
+       top.location = self.location;
+   }
+</script>
+
 <link rel="shortcut icon" href="[% IF ( OpacFavicon ) %][% OpacFavicon %][% ELSE %][% interface %]/[% theme %]/images/favicon.ico[% END %]" type="image/x-icon" />
 [% IF ( bidi ) %]
     <link rel="stylesheet" type="text/css" href="[% interface %]/[% theme %]/lib/bootstrap/css/bootstrap-rtl.min.css" />