VBA Right 関数でファイル拡張子を安全に判定!システムセキュリティ強化の実践テクニック
Excel VBAでシステムを構築している皆さん、ファイルアップロード機能の実装時に「ユーザーが意図しないファイル形式(例えば.exeファイルなど)をアップロードしてしまわないか」とヒヤヒヤした経験はありませんか?セキュリティ対策はシステムの信頼性を左右する重要な要素です。この記事では、VBAのRight関数を賢く使い、ファイル拡張子を正確に判定して不正なアップロードを防ぐための実践的なテクニックをご紹介します。
コピペOK!ファイル拡張子判定のVBA実務コード
ここでは、VBAのRight関数とInStrRev関数を組み合わせて、ファイル名から正確に拡張子を抽出し、指定された許可リストと照合するコードをご紹介します。このコードをあなたのシステムに組み込むことで、ファイルアップロード時のセキュリティを向上させることができます。
Sub ファイル拡張子判定とセキュリティチェック()
Dim fileName As String
Dim fileExtension As String
Dim dotPos As Long
Dim allowedExtensions As Variant ' 許可する拡張子のリスト
' 【重要】ここに判定したいファイル名を入力
' 例: fileName = "report.xlsx"
' 例: fileName = "document.pdf"
' 例: fileName = "image.jpeg"
' 例: fileName = "malicious.exe" ' 不許可ファイル
fileName = "report.xlsx" ' 今回の入力例
' 許可する拡張子を配列で定義(小文字で統一し、比較時にLCaseを使う)
' 必要に応じてリストを調整してください
allowedExtensions = Array("xlsx", "pdf", "jpg", "jpeg", "png", "doc", "docx", "xls", "xlsm", "txt", "csv")
' ----------------------------------------------------
' 拡張子を安全に抽出するロジック
' ----------------------------------------------------
' ファイル名の末尾から見て最初のドット(.)の位置を探す
' (例: "archive.tar.gz" の場合、最後のドットの前までを考慮)
dotPos = InStrRev(fileName, ".")
If dotPos > 0 Then
' ドット以降の文字列(拡張子)を取得
' Len(fileName) - dotPos で、ドット以降の文字数を正確に計算
fileExtension = LCase(Right(fileName, Len(fileName) - dotPos))
' 抽出した拡張子が許可リストに含まれているか判定
If IsExtensionAllowed(fileExtension, allowedExtensions) Then
Debug.Print "'" & fileName & "' は許可されたファイル形式です。(拡張子: ." & fileExtension & ")"
MsgBox "'" & fileName & "' は許可されたファイル形式です。", vbInformation, "拡張子判定結果"
Else
Debug.Print "'" & fileName & "' は許可されていないファイル形式です!(拡張子: ." & fileExtension & ")"
MsgBox "'" & fileName & "' は許可されていないファイル形式です!", vbCritical, "拡張子判定結果"
End If
Else
Debug.Print "'" & fileName & "' に拡張子が見つかりません。"
MsgBox "'" & fileName & "' に拡張子が見つかりません。", vbExclamation, "拡張子判定結果"
End If
End Sub
' ヘルパー関数: 拡張子が許可リストに含まれているか判定
Function IsExtensionAllowed(ext As String, allowedList As Variant) As Boolean
Dim item As Variant
For Each item In allowedList
If ext = item Then
IsExtensionAllowed = True
Exit Function
End If
Next item
IsExtensionAllowed = False
End Function
VBA `Right`関数の落とし穴と`InStrRev`による確実な拡張子抽出
ファイル拡張子の判定において、多くの人が陥りがちな落とし穴があります。それは、「拡張子は常に3文字である」という誤解です。例えば、.xlsxは4文字、.htmlは4文字、.jpegは4文字です。もし、安易にRight(ファイル名, 3)としてしまうと、次のような問題が発生します。
"report.xlsx"→"lsx"(本来の拡張子"xlsx"と異なる)"image.jpeg"→"peg"(本来の拡張子"jpeg"と異なる)"index.html"→"tml"(本来の拡張子"html"と異なる)
Right(ファイル名, 3) は危険です!
3文字固定の拡張子判定は、セキュリティホールとなるだけでなく、正常なファイルまで弾いてしまう誤動作の原因となります。特に、アップロードされたファイルから実行ファイル(.exe, .batなど)を除外しようとする際に、この誤った方法を使うと、思わぬ形式のファイルを見逃す可能性があります。
この問題を回避し、いかなるファイル名に対しても正確に拡張子を抽出するために必須となるのが、InStrRev関数です。
InStrRev(文字列, 検索文字): 文字列の末尾から検索文字を探し、その位置(先頭からの文字位置)を返します。これにより、ファイル名に含まれる複数のドットのうち、最も右にあるドット(=拡張子の区切り)を正確に特定できます。
例:InStrRev("document.v1.0.pdf", ".")は14を返します。- ドットの位置が分かれば、
Len(fileName) - dotPosでドット以降の文字数(拡張子の長さ)が正確に求められます。 - この長さを
Right関数の第2引数に渡すことで、可変長の拡張子も確実に抽出できるのです。
まとめ:セキュリティは「正確な拡張子判定」から
VBAでファイル拡張子を判定する際には、単にRight関数を使うだけでなく、InStrRev関数と組み合わせることで、どんなファイル名にも対応できる堅牢な処理を実装できます。これにより、意図しないファイル形式のアップロードを未然に防ぎ、あなたのシステムをセキュリティリスクから守ることが可能です。本記事でご紹介したテクニックをぜひ活用し、より安全で信頼性の高いVBAシステムを構築してください。小さな工夫が、システムの大きな安全に繋がります。