UPD: Zip - Better suspicious symbolic links handling

This commit is contained in:
Alexander Koblov 2025-11-04 14:55:27 +03:00
commit 396d7b541a
5 changed files with 40 additions and 6 deletions

View file

@ -36,11 +36,9 @@ unit AbArcTyp;
interface
uses
{$IFDEF MSWINDOWS}
Windows,
{$ENDIF MSWINDOWS}
Classes,
Types,
DCStrUtils,
AbUtils,
DCBasicTypes;
@ -293,6 +291,7 @@ type
FSpanningThreshold : Int64;
FCompressionLevel : IntPtr;
FCompressionMethod : IntPtr;
FSuspiciousLinks : TStringList;
FItemList : TAbArchiveList;
FLogFile : string;
FLogging : Boolean;
@ -444,6 +443,7 @@ type
procedure TestTaggedItems;
procedure TestAt(Index : Integer);
procedure UnTagItems(const FileMask : string);
procedure VerifyItem(Item: TAbArchiveItem);
function StreamFindNext(out Item: TAbArchiveItem): Boolean; virtual;
procedure StreamSeekNext(ASkip: Boolean); virtual;
@ -2016,6 +2016,22 @@ begin
end;
end;
{ -------------------------------------------------------------------------- }
procedure TAbArchive.VerifyItem(Item: TAbArchiveItem);
var
Index: Integer;
AFileName: String;
begin
if FSuspiciousLinks.Count > 0 then
begin
AFileName := NormalizePathDelimiters(Item.FileName);
for Index := 0 to FSuspiciousLinks.Count - 1 do
begin
if IsInPath(FSuspiciousLinks[Index], AFileName, True, True) then
raise EInvalidOpException.Create(AbSuspiciousSymlinkOperation);
end;
end;
end;
{ -------------------------------------------------------------------------- }
function TAbArchive.StreamFindNext(out Item: TAbArchiveItem): Boolean;
begin
Result := False;

View file

@ -75,6 +75,7 @@ resourcestring
AbLogCreateErrorS = 'Error creating Log File';
AbMoveFileErrorS = 'Error Moving File %s to %s';
AbFileSizeTooBigS = 'File size is too big for archive type';
AbSuspiciousSymlinkOperation = 'Suspicious operation with symbolic link!';
AbNoCabinetDllErrorS = 'Cannot load cabinet.dll';
AbFCIFileOpenErrorS = 'FCI cannot open file';

View file

@ -449,6 +449,8 @@ type
public {methods}
constructor CreateFromStream(aStream : TStream; const aArchiveName : string);
override;
destructor Destroy;
override;
function StreamFindNext(out Item: TAbArchiveItem): Boolean; override;
procedure StreamSeekNext(ASkip: Boolean); override;
@ -2080,6 +2082,13 @@ begin
inherited;
FTarAutoHandle := True;
FArchFormat := OLDGNU_FORMAT; // Default for new archives
FSuspiciousLinks := TStringList.Create;
end;
destructor TAbTarArchive.Destroy;
begin
inherited Destroy;
FSuspiciousLinks.Free;
end;
function TAbTarArchive.StreamFindNext(out Item: TAbArchiveItem): Boolean;
@ -2251,7 +2260,9 @@ begin
AbCreateDirectory(UseName)
else begin
case (CurItem.Mode and $F000) of
AB_FMODE_FILE, AB_FMODE_FILE2: begin
AB_FMODE_FILE, AB_FMODE_FILE2:
begin
VerifyItem(CurItem);
OutStream := TFileStreamEx.Create(UseName, fmCreate or fmShareDenyNone);
try
try {OutStream}
@ -2280,7 +2291,7 @@ begin
AFileName := GetAbsoluteFileName(ExtractFilePath(UseName), LinkTarget);
end;
if not IsInPath(BaseDirectory, AFileName, True, True) then
raise EInvalidOpException.Create(EmptyStr);
FSuspiciousLinks.Add(NormalizePathDelimiters(CurItem.FileName));
end;
if not CreateSymLink(LinkTarget, UseName) then

View file

@ -1249,7 +1249,7 @@ begin
AbsolutePath := GetAbsoluteFileName(ExtractFilePath(UseName), LinkTarget);
end;
if not IsInPath(ZipArchive.BaseDirectory, AbsolutePath, True, True) then
raise EInvalidOpException.Create(EmptyStr);
ZipArchive.SuspiciousLinks.Add(NormalizePathDelimiters(Item.FileName));
end;
if not CreateSymLink(LinkTarget, UseName, UInt32(Item.NativeFileAttributes)) then
@ -1261,6 +1261,7 @@ begin
end;
end
else begin
ZipArchive.VerifyItem(Item);
OutStream := TFileStreamEx.Create(UseName, fmCreate or fmShareDenyWrite);
try
try {OutStream}

View file

@ -600,6 +600,9 @@ type
read GetItem
write PutItem; default;
property SuspiciousLinks : TStringList
read FSuspiciousLinks;
public {events}
property OnNeedPassword : TAbNeedPasswordEvent
read FOnNeedPassword write FOnNeedPassword;
@ -1943,6 +1946,7 @@ begin
FPasswordRetries := AbDefPasswordRetries;
FTempDir := '';
SpanningThreshold := AbDefZipSpanningThreshold;
FSuspiciousLinks := TStringList.Create;
end;
{ -------------------------------------------------------------------------- }
destructor TAbZipArchive.Destroy;
@ -1950,6 +1954,7 @@ begin
FInfo.Free;
FInfo := nil;
inherited Destroy;
FSuspiciousLinks.Free;
end;
{ -------------------------------------------------------------------------- }
function TAbZipArchive.CreateItem(const SourceFileName : string;