Windowsでインターネットからダウンロードしたファイルのブロックについて

`Windows`でインターネットからダウンロードしたファイルには下記画像のように、プロパティに`セキュリティ`表示がされるかと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/48a07d1e-9ad9-c25e-541a-9dc5cf2017c5.png)

こちらのブロックについて、`PowerShell`で解除できるコマンドレット`Unblock-File`のドキュメントを読んでいたら、記載があったのでまとめ。

## ドキュメント

[Unblock-File](https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.utility/unblock-file?view=powershell-7.3)
[5.1 NTFS Streams](https://learn.microsoft.com/ja-jp/openspecs/windows_protocols/ms-fscc/c54dec26-1551-4d3a-a0ea-4fa40f848eb3)
[5.6.1 Zone.Identifier Stream Name](https://learn.microsoft.com/ja-jp/openspecs/windows_protocols/ms-fscc/6e3f7352-d11c-4d76-8c39-2516a9df36e8)

## 本記事の環境

- Windows 10 21H2
- Edge バージョン 107.0.1418.42
- curl.exe 7.83.1 (Windows) libcurl/7.83.1 Schannel

## そもそもUnblock-Fileって何してるの？

[Unblock-File - 説明](https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.utility/unblock-file?view=powershell-7.3#description)

コマンドレットのドキュメントの説明に記載がありますが。
`Unblock-File`コマンドレットが内部的にしている動作は`Zone.Identifier 代替データストリーム`の情報を削除しているようです。

`Windows`では`代替データストリーム`の`Zone.Identifier`が`3`だったらインターネットから取得されたファイルを示すようなので、この情報を削除しています。

## 代替データストリームって？

`Alternate Data Stream`で代替データストリーム。

`NTFS`ファイルシステムではファイルデータ以外に代替データストリームとして様々な情報を追加できます。

ブラウザはインターネットからダウンロードしたファイルに、この代替データストリームの`ZoneId`を付与している。

## 代替データストリームを確認してみる（PowerShell）

代替データストリームの有無を確認するには`Get-Item`コマンドレットを利用します。

今回、`ZoneId`を付与した`ZoneIdあり.txt`と`ZoneID`を付与しない`ZoneIDなし.txt`を用意して、`Get-Item`コマンドレットの`Stream`オプションをつかって`Zone.Identifer`の有無を確認してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/0415eba4-fde4-b4d6-19b8-06737ac2b6b4.png)


`ZoneIdあり.txt`では情報が表示され、`ZoneIdなし.txt`のファイルは`alternate data stream`を開けないとエラーがでている事を確認できます。

## Edgeでgoogleのロゴ画像をダウンロードして代替データストリームの内容を確認してみる

`Get-Item`コマンドレットで`ZoneID`の有無を確認しましたが、内容を確認するには`Get-Content`コマンドレットで確認できます。

ためしに`google.com`からブラウザ（Edge）でロゴ画像をダウンロードしてきて`ZoneID`を確認してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/15e63a1f-d9aa-4c38-5d71-c615cda34633.png)

[google.com](google.com)からロゴをダウンロードすると`googlelogo_color_272x92dp.png`というファイルが保存されました。

`Get-Content`コマンドレットの`Stream`オプションで確認すると下記のように情報が取得できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/a08e81f0-808d-30a6-0e0e-cf969a664cfa.png)

`ZoneId`がインターネットから取得した事を表す`3`が設定されており。
またダウンロード元となった、`ReferrerUrl`と`HostUrl`の情報が付与されている事がわかります。

## 代替データストリームを確認してみる（CMD）

CMDでは`more`コマンドがADSデータストリームに対応しており取得できるようです。

```cmd
more < googlelogo_color_272x92dp.png:Zone.Identifier:$DATA
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/124637aa-42d4-47f9-46f2-59757a2d9fb3.png)

## 任意のファイルに代替データストリームのZone.Identifierに3 をフ付与してみる

[Set-Content - Streamオプション](https://learn.microsoft.com/ja-jp/powershell/module/Microsoft.PowerShell.Management/set-content?view=powershell-7#-stream)

PowerShellの`Set-Content`コマンドの`stream`オプションを利用して代替データストリームのコンテンツを作成、更新できます。

ここでは下記のコマンドを実行して`samplefile.txt`に`ZoneId`を付与してみます。

```powerhsell
# サンプルファイルの作成
New-Item -ItemType File .\samplefile.txt

# ZoneIdが付与されていない事を確認
Get-Item .\samplefile.txt -Stream "Zone.Identifier"

# ZoneIdを付与
Set-Content .\samplefile.txt -Stream "Zone.Identifier" -Value @("[ZoneTransfer]","ZoneId=3")

# ZoneIdが付与されている事を確認
Get-Item .\samplefile.txt -Stream "Zone.Identifier"

# ZoneIdの内容を確認
Get-Content .\samplefile.txt -Stream "Zone.Identifier"
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/46acb9ca-1acb-136c-9077-3f56c6f51aa4.png)

samplefile.txtに`ZoneId`が付与された事が確認できました。

## ダウンロードするアプリケーションによってはZoneIdが付与されない

ブラウザからではなくファイルをダウンロードする方法によっては`ZoneId`は付与されません。

`curl.exe` や `Invoke-WebRequest`　で試しに、googleのロゴをダウンロードしてみると`ZoneId`が付与されてない状態でダウンロードされる事が確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/4dd07da0-ec3e-2603-d909-ec19410c0b34.png)

## 総評

Windowsでブラウザからダウンロードしたファイルがインターネットからダウンロードされた物だと判別する仕組みは、NTFSファイルシステムの代替データストリームの`Zone.Identifier`を利用していると理解できたかと思います。