Is there a way to modify permissions for a file in a zip without unzipping the file? For clarification, I am not asking to change the contents of the file, but the Unix permissions that are set on one. I have not found an answer for that yet other than extracting and updating the file.
2 Answers
Yes, sometimes there is. Without going in too deep about the details, a Zip file has a list of entries for each file and then another entry at the end that summarizes them. The entries might or might not have file permissions, it depends on the tool (and its version), filesystem, Zip format, ... But if they do, you can modify them.
The following steps are tested on Debian 10.
Lets create a zip file:
$ echo "This is file 1" > file1.txt
$ chmod 777 file1.txt
$ echo "This is file 2" > file2.txt
$ chmod 555 file2.txt
$ zip files file?.txt
Then list the files and permissions:
$ zipinfo files.zip
Archive: files.zip
Zip file size: 344 bytes, number of entries: 2
-rwxrwxrwx 3.0 unx 15 tx stor 20-Jun-08 18:35 file1.txt
-r-xr-xr-x 3.0 unx 15 tx stor 20-Jun-08 18:30 file2.txt
2 files, 30 bytes uncompressed, 30 bytes compressed: 0.0%
Now, we could manually iterate through the entries, but there is a program that already does it and prints the result:
$ zipdetail files.zip
That outputs lots of information. You have the offset at the left and the name and contents of each field next to it.
We just want the Ext File Attributes
for each file:
$ zipdetails files.zip | egrep "Ext File Attributes|Filename"
001A Filename Length 0009
001E Filename 'file1.txt'
006C Filename Length 0009
0070 Filename 'file2.txt'
00C0 Filename Length 0009
00CA Ext File Attributes 81FF0000
00D2 Filename 'file1.txt'
010F Filename Length 0009
0119 Ext File Attributes 816D0001
0121 Filename 'file2.txt'
Now, let's modify the permissions on file2.txt
to make it 777
by writing 0x81FF0000
(the file attributes for file1.txt
to offset 0x0119
(decimal 281, the file attributes for file2.txt
) taking into account the endianness:
$ printf "\x00\x00\xff\x81" | dd of=files.zip bs=1 seek=281 count=4 conv=notrunc
And list the contents again:
$ zipinfo files.zip
Archive: files.zip
Zip file size: 344 bytes, number of entries: 2
-rwxrwxrwx 3.0 unx 15 tx stor 20-Jun-08 18:35 file1.txt
-rwxrwxrwx 3.0 unx 15 tx stor 20-Jun-08 18:30 file2.txt
2 files, 30 bytes uncompressed, 30 bytes compressed: 0.0%
Now both files share the same permissions.
If you want to set your own permissions you can copy them from an existing file in a Zip or check them here.

- 12,834
That is not possible.
ZIP file format does not originate from UNIX systems and it doesn't thus have any UNIX-related permission support.

- 1,376
unzip -Z file.zip
and you'll see the stored Unix file permissions (if any). – Per Lundberg Aug 10 '23 at 08:06