nntp2http.com
Posting
Suche
Optionen
Hilfe & Kontakt

Cancel-Lock in filter nnrpd.pl setzen

Von: Alexander Bartolich (alexander.bartolich@gmx.at) [Profil]
Datum: 30.06.2007 14:56
Message-ID: <f65jtg$8ul$2@news.albasani.net>
Newsgroup: de.comm.software.newsserver
Das folgende ist eine Proof-Of-Concept-Implementierung um unter
INN alle lokal eingelieferten Postings mit einem Cancel-Lock bzw.
Cancel-Key zu versehen.

Die Semantik von filter_post, %hdr, $user und $modify_headers in der
Datei filter_nnrpd.pl ist in der Datei "hook-perl" bzw. "hook-perl.gz"
beschrieben.

sub filter_post
{
add_cancel_lock(\%hdr, $user);

if (exists( $hdr{"Control"} ) &&
$hdr{"Control"} =~ m/^cancel\s+(<[^>]+>)/i)
{
my $key = calc_cancel_key($user, $1);
add_cancel_item(\%hdr, 'Cancel-Key', $key);
}
elsif (exists( $hdr{"Supersedes"} ))
{
my $key = calc_cancel_key($user, $hdr{"Supersedes"});
add_cancel_item(\%hdr, 'Cancel-Key', $key);
}

$modify_headers = 1;
return '';
}

Jedes Posting bekommt einen (zusätzlichen) Cancel-Lock.
Control: cancel <message_id>
und
Supersedes: <message_id>
bekommen eine Cancel-Key passend zur referenzierten ID.

Ein Supersede eines Cancel-Control würde zwei Cancel-Key
erfordern. Dies ist laut draft-ietf-usefor-cancel-lock-01.txt
nicht gestattet.

sub add_cancel_item($$$)
{
my ( $r_hdr, $name, $value ) = @_;
my $prefix = $r_hdr->{$name};
$prefix = defined($prefix) ? $prefix . ' sha1:' : 'sha1:';
$r_hdr->{$name} = $prefix . $value;
}

Mehrere Cancel-Key in einem Header-Field sind durch ein Leerzeichen
getrennt. Diese Implementierung beschränkt sich auf das Schema "sha1".

sub calc_cancel_key($$)
{
my ( $user, $message_id ) = @_;
return MIME::Base64::encode(
Digest::HMAC_SHA1::hmac_sha1($message_id, $user . $CANCEL_LOCK), ''
);
}

Die Berechnung des Cancel-Key folgt der Empfehlung des Draft, d.h.
eigentlich nehme ich den Newsreader slrn als Referenzimplementierung.

Der kritische Punkt dabei ist das zweite Argument von "hmac_sha1".
Die Konkatenation der User-ID mit einem Site-Key "$CANCEL_LOCK"
bedeutet, dass Benutzer nur für ihre eigenen Postings korrekte
Cancel-Key generiert bekommen.

Admin-Cancel sind dann nicht mehr so einfach möglich. Dazu muss der
Admin für die Cancel-Postings jeweils extra einen Cancel-Key erstellen.

Wenn man "$user . $CANCEL_LOCK" auf "$CANCEL_LOCK" reduziert,
fällt
dieses Problem weg. Allerdings kann dann jeder Benutzer jedes Postings
anderer Benutzer Canceln bzw. Superseden. Allerdings kann man diese
Lücke auch so abfangen, dass die User-ID des Zielpostings überprüft
wird, und Rogue Cancel (TM) dann gar nicht erst angenommen werden.

In jedem Fall bleibt "$CANCEL_LOCK" ein globaler Schlüssel, den man
nicht unterbrechungsfrei auswechseln kann. Gelangt $CANCEL_LOCK an
die Öffentlichkeit, könnte ein Angreifer den gesamten Postingbestand
eines Servers mit korrektem Cancel-Key abräumen.

Bei der Konkatenation mit User-ID und Site-Key bräuchte der Angreifer
dafür aber zusätzlich noch die Möglichkeit, die User-ID eines Postings
zu ermitteln. Zumindest bei und ist diese User-ID verschlüsselt, und
zwar mit einem Schlüssel, der sich leicht ändern lässt.

sub add_cancel_lock($$)
{
my ( $r_hdr, $user ) = @_;
my $key = calc_cancel_key($user, $r_hdr->{'Message-ID'});
my $lock = MIME::Base64::encode(Digest::SHA1::sha1($key), '');
add_cancel_item($r_hdr, 'Cancel-Lock', $lock);
}

--
news.albasani.net

[ Auf dieses Posting antworten ]

Antworten