diff --git a/bin/rt.in b/bin/rt.in
index 31aaa97..5ca2836 100755
--- a/bin/rt.in
+++ b/bin/rt.in
@@ -67,6 +67,7 @@ use HTTP::Request::Common;
 use HTTP::Headers;
 use Term::ReadLine;
 use Time::Local; # used in prettyshow
+use File::Temp;
 
 # strong (GSSAPI based) authentication is supported if the server does provide
 # it and the perl modules GSSAPI and LWP::Authen::Negotiate are installed
@@ -1470,23 +1471,20 @@ sub read_passwd {
 
 sub vi {
     my ($text) = @_;
-    my $file = "/tmp/rt.form.$$";
     my $editor = $ENV{EDITOR} || $ENV{VISUAL} || "vi";
 
     local $/ = undef;
 
-    open( my $handle, '>', $file ) or die "$file: $!\n";
+    my $handle = File::Temp->new;
     print $handle $text;
     close($handle);
 
-    system($editor, $file) && die "Couldn't run $editor.\n";
+    system($editor, $handle->filename) && die "Couldn't run $editor.\n";
 
-    open( $handle, '<', $file ) or die "$file: $!\n";
+    open( $handle, '<', $handle->filename ) or die "$handle: $!\n";
     $text = <$handle>;
     close($handle);
 
-    unlink($file);
-
     return $text;
 }
 
diff --git b/etc/upgrade/4.0.13/schema.Oracle b/etc/upgrade/4.0.13/schema.Oracle
new file mode 100644
index 0000000..6ab7020
--- /dev/null
+++ b/etc/upgrade/4.0.13/schema.Oracle
@@ -0,0 +1,2 @@
+UPDATE Tickets SET Subject = REPLACE(Subject,CHR(10),''), Status = LOWER(Status);
+UPDATE Transactions SET OldValue = LOWER(OldValue), NewValue = LOWER(NewValue) WHERE Type = 'Status' AND Field = 'Status';
diff --git b/etc/upgrade/4.0.13/schema.Pg b/etc/upgrade/4.0.13/schema.Pg
new file mode 100644
index 0000000..8283f52
--- /dev/null
+++ b/etc/upgrade/4.0.13/schema.Pg
@@ -0,0 +1,2 @@
+UPDATE Tickets SET Subject = REPLACE(Subject,E'\n',''), Status = LOWER(Status);
+UPDATE Transactions SET OldValue = LOWER(OldValue), NewValue = LOWER(NewValue) WHERE Type = 'Status' AND Field = 'Status';
diff --git b/etc/upgrade/4.0.13/schema.mysql b/etc/upgrade/4.0.13/schema.mysql
new file mode 100644
index 0000000..03b54b5
--- /dev/null
+++ b/etc/upgrade/4.0.13/schema.mysql
@@ -0,0 +1,2 @@
+UPDATE Tickets SET Subject = REPLACE(Subject,'\n',''), Status = LOWER(Status);
+UPDATE Transactions SET OldValue = LOWER(OldValue), NewValue = LOWER(NewValue) WHERE Type = 'Status' AND Field = 'Status';
diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index 0bb7a83..88e1df1 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -561,6 +561,7 @@ sub MaybeRejectPrivateComponentRequest {
             / # leading slash
             ( Elements    |
               _elements   | # mobile UI
+              Callbacks   |
               Widgets     |
               autohandler | # requesting this directly is suspicious
               l (_unsafe)? ) # loc component
@@ -786,7 +787,7 @@ sub LoadSessionFromCookie {
     my $SessionCookie = ( $cookies{$cookiename} ? $cookies{$cookiename}->value : undef );
     tie %HTML::Mason::Commands::session, 'RT::Interface::Web::Session', $SessionCookie;
     unless ( $SessionCookie && $HTML::Mason::Commands::session{'_session_id'} eq $SessionCookie ) {
-        undef $cookies{$cookiename};
+        InstantiateNewSession();
     }
     if ( int RT->Config->Get('AutoLogoff') ) {
         my $now = int( time / 60 );
@@ -906,15 +907,15 @@ sub StaticFileHeaders {
 Takes C<PATH> and returns a boolean indicating that the user-specified partial
 component path is safe.
 
-Currently "safe" means that the path does not start with a dot (C<.>) and does
-not contain a slash-dot C</.>.
+Currently "safe" means that the path does not start with a dot (C<.>), does
+not contain a slash-dot C</.>, and does not contain any nulls.
 
 =cut
 
 sub ComponentPathIsSafe {
     my $self = shift;
     my $path = shift;
-    return $path !~ m{(?:^|/)\.};
+    return $path !~ m{(?:^|/)\.} and $path !~ m{\0};
 }
 
 =head2 PathIsSafe
diff --git a/lib/RT/Lifecycle.pm b/lib/RT/Lifecycle.pm
index 056599e..a6d6c3b 100644
--- a/lib/RT/Lifecycle.pm
+++ b/lib/RT/Lifecycle.pm
@@ -411,8 +411,8 @@ sub Transitions {
     return %{ $self->{'data'}{'transitions'} || {} }
         unless @_;
 
-    my $status = shift;
-    return @{ $self->{'data'}{'transitions'}{ $status || '' } || [] };
+    my $status = shift || '';
+    return @{ $self->{'data'}{'transitions'}{ lc $status } || [] };
 }
 
 =head1 IsTransition
@@ -439,8 +439,8 @@ be checked on the ticket.
 
 sub CheckRight {
     my $self = shift;
-    my $from = shift;
-    my $to = shift;
+    my $from = lc shift;
+    my $to = lc shift;
     if ( my $rights = $self->{'data'}{'rights'} ) {
         my $check =
             $rights->{ $from .' -> '. $to }
@@ -536,10 +536,11 @@ pairs:
 sub Actions {
     my $self = shift;
     my $from = shift || return ();
+    $from = lc $from;
 
     $self->FillCache unless keys %LIFECYCLES_CACHE;
 
-    my @res = grep $_->{'from'} eq $from || ( $_->{'from'} eq '*' && $_->{'to'} ne $from ),
+    my @res = grep lc $_->{'from'} eq $from || ( $_->{'from'} eq '*' && lc $_->{'to'} ne $from ),
         @{ $self->{'data'}{'actions'} };
 
     # skip '* -> x' if there is '$from -> x'
@@ -633,6 +634,13 @@ sub ForLocalization {
 
 sub loc { return RT->SystemUser->loc( @_ ) }
 
+sub CanonicalCase {
+    my $self = shift;
+    my ($status) = @_;
+    return undef unless defined $status;
+    return($self->{data}{canonical_case}{lc $status} || lc $status);
+}
+
 sub FillCache {
     my $self = shift;
 
@@ -647,45 +655,123 @@ sub FillCache {
         active => [],
         inactive => [],
     );
-    foreach my $lifecycle ( values %LIFECYCLES_CACHE ) {
-        my @res;
+    foreach my $name ( keys %LIFECYCLES_CACHE ) {
+        next if $name eq "__maps__";
+        my $lifecycle = $LIFECYCLES_CACHE{$name};
+
+        my @statuses;
+        $lifecycle->{canonical_case} = {};
         foreach my $type ( qw(initial active inactive) ) {
-            push @{ $all{ $type } }, @{ $lifecycle->{ $type } || [] };
-            push @res,               @{ $lifecycle->{ $type } || [] };
+            for my $status (@{ $lifecycle->{ $type } || [] }) {
+                if (exists $lifecycle->{canonical_case}{lc $status}) {
+                    warn "Duplicate status @{[lc $status]} in lifecycle $name";
+                } else {
+                    $lifecycle->{canonical_case}{lc $status} = $status;
+                }
+                push @{ $all{ $type } }, $status;
+                push @statuses, $status;
+            }
+        }
+
+        # Lower-case for consistency
+        # ->{actions} are handled below
+        for my $state (keys %{ $lifecycle->{defaults} || {} }) {
+            my $status = $lifecycle->{defaults}{$state};
+            warn "Nonexistant status @{[lc $status]} in default states in $name lifecycle"
+                unless $lifecycle->{canonical_case}{lc $status};
+            $lifecycle->{defaults}{$state} =
+                $lifecycle->{canonical_case}{lc $status} || lc $status;
+        }
+        for my $from (keys %{ $lifecycle->{transitions} || {} }) {
+            warn "Nonexistant status @{[lc $from]} in transitions in $name lifecycle"
+                unless $from eq '' or $lifecycle->{canonical_case}{lc $from};
+            for my $status ( @{delete($lifecycle->{transitions}{$from}) || []} ) {
+                warn "Nonexistant status @{[lc $status]} in transitions in $name lifecycle"
+                    unless $lifecycle->{canonical_case}{lc $status};
+                push @{ $lifecycle->{transitions}{lc $from} },
+                    $lifecycle->{canonical_case}{lc $status} || lc $status;
+            }
+        }
+        for my $schema (keys %{ $lifecycle->{rights} || {} }) {
+            my ($from, $to) = split /\s*->\s*/, $schema, 2;
+            unless ($from and $to) {
+                warn "Invalid right transition $schema in $name lifecycle";
+                next;
+            }
+            warn "Nonexistant status @{[lc $from]} in right transition in $name lifecycle"
+                unless $from eq '*' or $lifecycle->{canonical_case}{lc $from};
+            warn "Nonexistant status @{[lc $to]} in right transition in $name lifecycle"
+                unless $to eq '*' or $lifecycle->{canonical_case}{lc $to};
+            $lifecycle->{rights}{lc($from) . " -> " .lc($to)}
+                = delete $lifecycle->{rights}{$schema};
         }
 
         my %seen;
-        @res = grep !$seen{ lc $_ }++, @res;
-        $lifecycle->{''} = \@res;
+        @statuses = grep !$seen{ $_ }++, @statuses;
+        $lifecycle->{''} = \@statuses;
 
         unless ( $lifecycle->{'transitions'}{''} ) {
-            $lifecycle->{'transitions'}{''} = [ grep $_ ne 'deleted', @res ];
+            $lifecycle->{'transitions'}{''} = [ grep $_ ne 'deleted', @statuses ];
         }
-    }
-    foreach my $type ( qw(initial active inactive), '' ) {
-        my %seen;
-        @{ $all{ $type } } = grep !$seen{ lc $_ }++, @{ $all{ $type } };
-        push @{ $all{''} }, @{ $all{ $type } } if $type;
-    }
-    $LIFECYCLES_CACHE{''} = \%all;
 
-    foreach my $lifecycle ( values %LIFECYCLES_CACHE ) {
-        my @res;
+        my @actions;
         if ( ref $lifecycle->{'actions'} eq 'HASH' ) {
             foreach my $k ( sort keys %{ $lifecycle->{'actions'} } ) {
-                push @res, $k, $lifecycle->{'actions'}{ $k };
+                push @actions, $k, $lifecycle->{'actions'}{ $k };
             }
         } elsif ( ref $lifecycle->{'actions'} eq 'ARRAY' ) {
-            @res = @{ $lifecycle->{'actions'} };
+            @actions = @{ $lifecycle->{'actions'} };
         }
 
-        my @tmp = splice @res;
-        while ( my ($transition, $info) = splice @tmp, 0, 2 ) {
+        $lifecycle->{'actions'} = [];
+        while ( my ($transition, $info) = splice @actions, 0, 2 ) {
             my ($from, $to) = split /\s*->\s*/, $transition, 2;
-            push @res, { %$info, from => $from, to => $to };
+            unless ($from and $to) {
+                warn "Invalid action status change $transition in $name lifecycle";
+                next;
+            }
+            warn "Nonexistant status @{[lc $from]} in action in $name lifecycle"
+                unless $from eq '*' or $lifecycle->{canonical_case}{lc $from};
+            warn "Nonexistant status @{[lc $to]} in action in $name lifecycle"
+                unless $to eq '*' or $lifecycle->{canonical_case}{lc $to};
+            push @{ $lifecycle->{'actions'} },
+                { %$info,
+                  from => ($lifecycle->{canonical_case}{lc $from} || lc $from),
+                  to   => ($lifecycle->{canonical_case}{lc $to}   || lc $to),   };
         }
-        $lifecycle->{'actions'} = \@res;
     }
+
+    # Lower-case the transition maps
+    for my $mapname (keys %{ $LIFECYCLES_CACHE{'__maps__'} || {} }) {
+        my ($from, $to) = split /\s*->\s*/, $mapname, 2;
+        unless ($from and $to) {
+            warn "Invalid lifecycle mapping $mapname";
+            next;
+        }
+        warn "Nonexistant lifecycle $from in $mapname lifecycle map"
+            unless $LIFECYCLES_CACHE{$from};
+        warn "Nonexistant lifecycle $to in $mapname lifecycle map"
+            unless $LIFECYCLES_CACHE{$to};
+        my $map = delete $LIFECYCLES_CACHE{'__maps__'}{$mapname};
+        $LIFECYCLES_CACHE{'__maps__'}{"$from -> $to"} = $map;
+        for my $status (keys %{ $map }) {
+            warn "Nonexistant status @{[lc $status]} in $from in $mapname lifecycle map"
+                if $LIFECYCLES_CACHE{$from}
+                    and not $LIFECYCLES_CACHE{$from}{canonical_case}{lc $status};
+            warn "Nonexistant status @{[lc $map->{$status}]} in $from in $mapname lifecycle map"
+                if $LIFECYCLES_CACHE{$to}
+                    and not $LIFECYCLES_CACHE{$to}{canonical_case}{lc $map->{$status}};
+            $map->{lc $status} = lc delete $map->{$status};
+        }
+    }
+
+    foreach my $type ( qw(initial active inactive), '' ) {
+        my %seen;
+        @{ $all{ $type } } = grep !$seen{ $_ }++, @{ $all{ $type } };
+        push @{ $all{''} }, @{ $all{ $type } } if $type;
+    }
+    $LIFECYCLES_CACHE{''} = \%all;
+
     return;
 }
 
diff --git a/lib/RT/Ticket.pm b/lib/RT/Ticket.pm
index 91711e4..aa2771d 100644
--- a/lib/RT/Ticket.pm
+++ b/lib/RT/Ticket.pm
@@ -298,6 +298,7 @@ sub Create {
         $args{'Status'} = $cycle->DefaultOnCreate;
     }
 
+    $args{'Status'} = lc $args{'Status'};
     unless ( $cycle->IsValid( $args{'Status'} ) ) {
         return ( 0, 0,
             $self->loc("Status '[_1]' isn't a valid status for tickets in this queue.",
@@ -459,6 +460,8 @@ sub Create {
         }
     }
 
+    $args{'Subject'} =~ s/\n//g;
+
     $RT::Handle->BeginTransaction();
 
     my %params = (
@@ -1715,7 +1718,7 @@ sub SetQueue {
         unless ( $old_lifecycle->HasMoveMap( $new_lifecycle ) ) {
             return ( 0, $self->loc("There is no mapping for statuses between these queues. Contact your system administrator.") );
         }
-        $new_status = $old_lifecycle->MoveMap( $new_lifecycle )->{ $self->Status };
+        $new_status = $old_lifecycle->MoveMap( $new_lifecycle )->{ lc $self->Status };
         return ( 0, $self->loc("Mapping between queues' lifecycles is incomplete. Contact your system administrator.") )
             unless $new_status;
     }
@@ -1812,6 +1815,13 @@ sub QueueObj {
     return ($self->{_queue_obj});
 }
 
+sub SetSubject {
+    my $self = shift;
+    my $value = shift;
+    $value =~ s/\n//g;
+    return $self->_Set( Field => 'Subject', Value => $value );
+}
+
 =head2 SubjectTag
 
 Takes nothing. Returns SubjectTag for this ticket. Includes
@@ -3109,7 +3119,12 @@ sub ValidateStatus {
     return 0;
 }
 
-
+sub Status {
+    my $self = shift;
+    my $value = $self->_Value( 'Status' );
+    return $value unless $self->QueueObj;
+    return $self->QueueObj->Lifecycle->CanonicalCase( $value );
+}
 
 =head2 SetStatus STATUS
 
@@ -3139,7 +3154,7 @@ sub SetStatus {
 
     my $lifecycle = $self->QueueObj->Lifecycle;
 
-    my $new = $args{'Status'};
+    my $new = lc $args{'Status'};
     unless ( $lifecycle->IsValid( $new ) ) {
         return (0, $self->loc("Status '[_1]' isn't a valid status for tickets in this queue.", $self->loc($new)));
     }
@@ -3187,7 +3202,7 @@ sub SetStatus {
     #Actually update the status
     my ($val, $msg)= $self->_Set(
         Field           => 'Status',
-        Value           => $args{Status},
+        Value           => $new,
         TimeTaken       => 0,
         CheckACL        => 0,
         TransactionType => 'Status',
diff --git a/lib/RT/Tickets.pm b/lib/RT/Tickets.pm
index 6dd23e0..5fb674d 100644
--- a/lib/RT/Tickets.pm
+++ b/lib/RT/Tickets.pm
@@ -375,6 +375,8 @@ sub _EnumLimit {
         my $o     = $class->new( $sb->CurrentUser );
         $o->Load($value);
         $value = $o->Id;
+    } elsif ($field eq "Status") {
+        $value = lc $value;
     }
     $sb->_SQLLimit(
         FIELD    => $field,
diff --git a/lib/RT/Transaction.pm b/lib/RT/Transaction.pm
index 5b3641f..c8c22f8 100644
--- a/lib/RT/Transaction.pm
+++ b/lib/RT/Transaction.pm
@@ -635,11 +635,14 @@ sub BriefDescription {
                 return ( $self->loc( "[_1] deleted", $obj_type ) );
             }
             else {
+                my $canon = $self->Object->can("QueueObj")
+                    ? sub { $self->Object->QueueObj->Lifecycle->CanonicalCase(@_) }
+                    : sub { return $_[0] };
                 return (
                     $self->loc(
                         "Status changed from [_1] to [_2]",
-                        "'" . $self->loc( $self->OldValue ) . "'",
-                        "'" . $self->loc( $self->NewValue ) . "'"
+                        "'" . $self->loc( $canon->($self->OldValue) ) . "'",
+                        "'" . $self->loc( $canon->($self->NewValue) ) . "'"
                     )
                 );
 
diff --git a/share/html/Admin/Tools/Shredder/Elements/Object/RT--Attachment b/share/html/Admin/Tools/Shredder/Elements/Object/RT--Attachment
index 0da910d..0544a36 100644
--- a/share/html/Admin/Tools/Shredder/Elements/Object/RT--Attachment
+++ b/share/html/Admin/Tools/Shredder/Elements/Object/RT--Attachment
@@ -49,6 +49,6 @@
 $Object => undef
 </%ARGS>
 % my $name = (defined $Object->Filename and length $Object->Filename) ? $Object->Filename : loc("(no value)");
-<a href="<% RT->Config->Get('WebPath') %>/Ticket/Attachment/<% $Object->TransactionId %>/<% $Object->id %>/">
+<a href="<% RT->Config->Get('WebPath') %>/Ticket/Attachment/<% $Object->TransactionId %>/<% $Object->id %>/<% $Object->Filename |un %>">
 <% loc('Attachment') %>(<% loc('id') %>:<% $Object->id %>, <% loc('Filename') %>: <% $name %>)
 </a>
diff --git a/share/html/Download/CustomFieldValue/dhandler b/share/html/Download/CustomFieldValue/dhandler
index 6db45ed..2329ffd 100644
--- a/share/html/Download/CustomFieldValue/dhandler
+++ b/share/html/Download/CustomFieldValue/dhandler
@@ -64,7 +64,7 @@ unless ($OCFV->id) {
 my $content_type = $OCFV->ContentType || 'text/plain';
     
 if (RT->Config->Get('AlwaysDownloadAttachments')) {
-    $r->headers_out->{'Content-Disposition'} = "attachment; filename=" . $OCFV->Content;
+    $r->headers_out->{'Content-Disposition'} = "attachment";
 }
 elsif (!RT->Config->Get('TrustHTMLAttachments')) {
     $content_type = 'text/plain' if ($content_type =~ /^text\/html/i);
diff --git a/share/html/Elements/ColumnMap b/share/html/Elements/ColumnMap
index 7295e3f..7ba2fc2 100644
--- a/share/html/Elements/ColumnMap
+++ b/share/html/Elements/ColumnMap
@@ -170,8 +170,10 @@ $m->callback( COLUMN_MAP => $COLUMN_MAP, CallbackName => 'Once', CallbackOnce =>
 $m->callback( COLUMN_MAP => $COLUMN_MAP );
 
 # first deal with class specific things
-my $class_map = $m->comp("/Elements/$Class/ColumnMap", Attr => $Attr, Name => $Name );
-return $class_map if defined $class_map;
+if (RT::Interface::Web->ComponentPathIsSafe($Class) and $m->comp_exists("/Elements/$Class/ColumnMap")) {
+    my $class_map = $m->comp("/Elements/$Class/ColumnMap", Attr => $Attr, Name => $Name );
+    return $class_map if defined $class_map;
+}
 return GetColumnMapEntry( Map => $COLUMN_MAP, Name => $Name, Attribute => $Attr );
 
 </%INIT>
diff --git a/share/html/Elements/EditCustomFieldBinary b/share/html/Elements/EditCustomFieldBinary
index 0a20985..54cb92e 100644
--- a/share/html/Elements/EditCustomFieldBinary
+++ b/share/html/Elements/EditCustomFieldBinary
@@ -47,7 +47,7 @@
 %# END BPS TAGGED BLOCK }}}
 % while ( $Values and my $value = $Values->Next ) {
 %# XXX - let user download the file(s) here?
-<input type="checkbox" class="checkbox" name="<%$NamePrefix%><%$CustomField->Id%>-DeleteValueIds" class="CF-<%$CustomField->id%>-Edit" value="<% $value->Id %>" /><a href="<%RT->Config->Get('WebPath')%>/Download/CustomFieldValue/<% $value->Id %>/<% $value->Content %>"><% $value->Content %></a><br />
+<input type="checkbox" class="checkbox" name="<%$NamePrefix%><%$CustomField->Id%>-DeleteValueIds" class="CF-<%$CustomField->id%>-Edit" value="<% $value->Id %>" /><a href="<%RT->Config->Get('WebPath')%>/Download/CustomFieldValue/<% $value->Id %>/<% $value->Content |un %>"><% $value->Content %></a><br />
 % }
 % if (!$MaxValues || !$Values || $Values->Count < $MaxValues) {
 <input type="file" name="<% $NamePrefix %><% $CustomField->Id %>-Upload" class="CF-<%$CustomField->id%>-Edit" />
diff --git a/share/html/Elements/MakeClicky b/share/html/Elements/MakeClicky
index 57964f7..c32b306 100644
--- a/share/html/Elements/MakeClicky
+++ b/share/html/Elements/MakeClicky
@@ -48,20 +48,27 @@
 <%ONCE>
 use Regexp::Common qw(URI);
 
+my $escaper = sub {
+    my $content = shift;
+    RT::Interface::Web::EscapeUTF8( \$content );
+    return $content;
+};
+
 my %actions = (
     default => sub {
         my %args = @_;
-        return $args{value};
+        return $escaper->($args{value});
     },
     url => sub {
         my %args = @_;
+        $args{value} = $escaper->($args{value});
         my $result = qq{[<a target="new" href="$args{value}">}. loc('Open URL') .qq{</a>]};
         return $args{value} . qq{ <span class="clickylink">$result</span>};
     },
     url_overwrite => sub {
         my %args = @_;
-        my $result = qq{<a target="new" href="$args{'value'}">};
-        $result .= qq{$args{'value'}</a>};
+        $args{value} = $escaper->($args{value});
+        my $result = qq{<a target="new" href="$args{value}">$args{value}</a>};
         return qq{<span class="clickylink">$result</span>};
     },
 );
@@ -89,12 +96,6 @@ my $handle = sub {
     }
 };
 
-my $escaper = sub {
-    my $content = shift;
-    RT::Interface::Web::EscapeUTF8( \$content );
-    return $content;
-};
-
 # Hook to add more Clicky types
 # XXX Have to have Page argument, as Mason gets caller wrong in Callback?
 # This happens as we are in <%ONCE> block
diff --git a/share/html/Elements/ShowCustomFieldBinary b/share/html/Elements/ShowCustomFieldBinary
index 04e6877..6fa0c76 100644
--- a/share/html/Elements/ShowCustomFieldBinary
+++ b/share/html/Elements/ShowCustomFieldBinary
@@ -45,7 +45,7 @@
 %# those contributions and any derivatives thereof.
 %#
 %# END BPS TAGGED BLOCK }}}
-<a href="<%RT->Config->Get('WebPath')%>/Download/CustomFieldValue/<% $Object->Id %>/<% $Object->Content |u %>"><% $Object->Content %></a>
+<a href="<%RT->Config->Get('WebPath')%>/Download/CustomFieldValue/<% $Object->Id %>/<% $Object->Content |un %>"><% $Object->Content %></a>
 <%ARGS>
 $Object => undef
 </%ARGS>
diff --git a/share/html/NoAuth/Logout.html b/share/html/NoAuth/Logout.html
index 20024cc..8f10131 100644
--- a/share/html/NoAuth/Logout.html
+++ b/share/html/NoAuth/Logout.html
@@ -76,7 +76,7 @@ $m->callback( %ARGS, URL => \$URL );
 $m->callback( %ARGS, CallbackName => 'BeforeSessionDelete' );
 
 if (keys %session) {
-    tied(%session)->delete;
+    RT::Interface::Web::InstantiateNewSession();
     $session{'CurrentUser'} = RT::CurrentUser->new;
 }
 
diff --git a/share/html/REST/1.0/logout b/share/html/REST/1.0/logout
index 660c123..7bf2804 100644
--- a/share/html/REST/1.0/logout
+++ b/share/html/REST/1.0/logout
@@ -46,6 +46,9 @@
 %#
 %# END BPS TAGGED BLOCK }}}
 <%PERL>
-tied(%session)->delete if keys %session;
+if (keys %session) {
+    RT::Interface::Web::InstantiateNewSession();
+    $session{CurrentUser} = RT::CurrentUser->new();
+}
 </%PERL>
 RT/<% $RT::VERSION %> 200 Ok
diff --git a/share/html/Ticket/Attachment/dhandler b/share/html/Ticket/Attachment/dhandler
index 86c99e1..8e9b4a2 100644
--- a/share/html/Ticket/Attachment/dhandler
+++ b/share/html/Ticket/Attachment/dhandler
@@ -70,7 +70,7 @@
      my $content_type = $AttachmentObj->ContentType || 'text/plain';
 
      if (RT->Config->Get('AlwaysDownloadAttachments')) {
-         $r->headers_out->{'Content-Disposition'} = "attachment; filename=" . $AttachmentObj->Filename;
+         $r->headers_out->{'Content-Disposition'} = "attachment";
      }
      elsif (!RT->Config->Get('TrustHTMLAttachments')) {
          $content_type = 'text/plain' if ($content_type =~ /^text\/html/i);
diff --git a/share/html/Ticket/Elements/ShowAttachments b/share/html/Ticket/Elements/ShowAttachments
index 12130e4..7f1a835 100644
--- a/share/html/Ticket/Elements/ShowAttachments
+++ b/share/html/Ticket/Elements/ShowAttachments
@@ -82,7 +82,7 @@ if ($size) {
 </%PERL>
 
 <li><font size="-2">
-<a href="<%RT->Config->Get('WebPath')%>/Ticket/Attachment/<%$rev->TransactionId%>/<%$rev->Id%>/<%$rev->Filename | u%>">
+<a href="<%RT->Config->Get('WebPath')%>/Ticket/Attachment/<%$rev->TransactionId%>/<%$rev->Id%>/<%$rev->Filename | un %>">
 % my $desc = loc("[_1] ([_2]) by [_3]", $rev->CreatedAsString, $size, $m->scomp('/Elements/ShowUser', User => $rev->CreatorObj));
 <% $desc |n%>
 </a>
diff --git a/share/html/Ticket/Elements/ShowTransactionAttachments b/share/html/Ticket/Elements/ShowTransactionAttachments
index 95a2341..c5c38ef 100644
--- a/share/html/Ticket/Elements/ShowTransactionAttachments
+++ b/share/html/Ticket/Elements/ShowTransactionAttachments
@@ -257,12 +257,13 @@ my $render_attachment = sub {
         }
 
         my $filename =  length $name ? $name : loc('(untitled)');
+        my $efilename = $m->interp->apply_escapes( $filename, 'h' );
         $m->out('<img'
               . ' alt="'
-              . $filename
+              . $efilename
               . '"' 
               . ' title="'
-              . $filename
+              . $efilename
               . '"' 
               . ' src="'
               . $AttachPath . '/'
diff --git a/share/html/m/logout b/share/html/m/logout
index cebaa32..6ef78e7 100644
--- a/share/html/m/logout
+++ b/share/html/m/logout
@@ -47,7 +47,7 @@
 %# END BPS TAGGED BLOCK }}}
 <%init>
 if (keys %session) {
-    tied(%session)->delete;
+    RT::Interface::Web::InstantiateNewSession();
     $session{'CurrentUser'} = RT::CurrentUser->new;
 }
 RT::Interface::Web::Redirect(RT->Config->Get('WebURL')."m/");
diff --git a/share/html/m/ticket/show b/share/html/m/ticket/show
index f6ffe88..fb74d29 100644
--- a/share/html/m/ticket/show
+++ b/share/html/m/ticket/show
@@ -338,7 +338,7 @@ if ($size) {
 </%PERL>
 
 <li><font size="-2">
-<a href="<%RT->Config->Get('WebPath')%>/Ticket/Attachment/<%$rev->TransactionId%>/<%$rev->Id%>/<%$rev->Filename | u%>">
+<a href="<%RT->Config->Get('WebPath')%>/Ticket/Attachment/<%$rev->TransactionId%>/<%$rev->Id%>/<%$rev->Filename | un%>">
 <&|/l, $rev->CreatedAsString, $size, $rev->CreatorObj->Name &>[_1] ([_2]) by [_3]</&>
 </a>
 </font></li>
