validSymlinkName checks the per-component name of a symlink for dotfile names that attackers can use to trick a checkout into writing a dangerous symlink. Each path component is compared against .gitmodules case-insensitively, against its NTFS variants (e.g. ".gitmodules .", ".gitmodules::$INDEX_ALL
(name string)
| 246 | // |
| 247 | // [1]: https://github.com/git/git/blob/v2.54.0/read-cache.c#L1004-L1024 |
| 248 | func (sfs *worktreeFilesystem) validSymlinkName(name string) error { |
| 249 | parts := strings.FieldsFunc(name, func(r rune) bool { |
| 250 | return r == '/' || r == '\\' |
| 251 | }) |
| 252 | for _, part := range parts { |
| 253 | if strings.EqualFold(part, gitmodulesFile) { |
| 254 | return ErrGitModulesSymlink |
| 255 | } |
| 256 | if sfs.protectNTFS && pathutil.IsNTFSDotGitmodules(part) { |
| 257 | return ErrGitModulesSymlink |
| 258 | } |
| 259 | if sfs.protectHFS && pathutil.IsHFSDotGitmodules(part) { |
| 260 | return ErrGitModulesSymlink |
| 261 | } |
| 262 | } |
| 263 | return nil |
| 264 | } |
no test coverage detected