flipped-aurora/gin-vue-admin · error
日志文件路径不合法
Error message
日志文件路径不合法
What it means
ErrInvalidLogPath indicates the requested log file path is not legal — the service rejects anything that escapes the configured log root or otherwise fails path-segment validation. validateLogAPIPath checks the path segments (e.g. rejecting traversal like "../"), and openValidatedLogFile also returns it when the date entry is a symlink or not a real directory. It is a security guard against path traversal and symlink attacks on the log viewer.
Source
Thrown at server/service/system/sys_log_viewer.go:31
"sort"
"strings"
"time"
"github.com/flipped-aurora/gin-vue-admin/server/global"
systemReq "github.com/flipped-aurora/gin-vue-admin/server/model/system/request"
systemRes "github.com/flipped-aurora/gin-vue-admin/server/model/system/response"
)
const (
DefaultLogChunkLines = 500
MaxLogChunkBytes = 2 * 1024 * 1024
logReadBlockSize = 64 * 1024
)
var (
ErrInvalidLogMonth = errors.New("日志月份格式不正确")
ErrInvalidLogDate = errors.New("日志日期格式不正确")
ErrInvalidLogPath = errors.New("日志文件路径不合法")
ErrLogFileNotFound = errors.New("日志文件不存在")
ErrLogFileUnreadable = errors.New("日志文件不可读取")
ErrLogRootUnavailable = errors.New("日志目录不可读取")
)
type LogViewerService struct{}
func (s *LogViewerService) ListDates(ctx context.Context, month string) (result systemRes.LogDateList, err error) {
result = systemRes.LogDateList{Month: month, Dates: make([]systemRes.LogDateItem, 0)}
if err = validateLogMonth(month); err != nil {
return result, err
}
logRoot, exists, err := openConfiguredLogRoot()
if err != nil {
return result, err
}
if !exists {View on GitHub (pinned to 3136500ef3)
Solutions
- Request only files discovered via the ListFiles/ListDates APIs; never build paths from user input.
- Remove "..", absolute prefixes, and backslashes from any constructed path; send a plain relative file name.
- Check the log root on disk: date entries must be real directories, not symlinks; restructure or remove symlinked log dirs.
- Keep log layout aligned with the expected <logRoot>/<YYYY-MM-DD>/<name>.log structure.
Example fix
// before GET /logViewer/content?date=2025-08-01&path=../../etc/passwd // ErrInvalidLogPath // after GET /logViewer/content?date=2025-08-01&path=gva-2025-08-01.log
Defensive patterns
Strategy: validation
Validate before calling
func isSafeLogPath(p string) bool {
if p == "" || strings.HasPrefix(p, "/") || strings.Contains(p, "\\") {
return false
}
for _, seg := range strings.Split(p, "/") {
if seg == "" || seg == "." || seg == ".." {
return false
}
}
return true
} Type guard
func isKnownLogFile(path string, known []string) bool {
return slices.Contains(known, path)
} Try / catch
content, err := client.ReadContent(ctx, date, path)
if err != nil && errors.Is(err, ErrInvalidLogPath) {
// reject the input; do NOT retry with a modified path — refresh the file list instead
} Prevention
- Only use file names returned by ListFiles; never assemble paths from user input.
- Reject any path containing "..", leading "/", or backslashes before sending.
- Keep log directories real directories — avoid symlinks under the log root.
- Monitor rejected-path attempts as a security signal.
When it happens
Trigger: ReadContent with apiPath containing "..", leading "/", backslashes, or unexpected segments; passing a date whose directory under the log root is a symlink or a regular file instead of a real directory; any non-whitelisted file path within a date directory.
Common situations: Probing/scanning clients attempting path traversal; old log layouts where date entries are files or symlinks; frontends concatenating raw user paths instead of whitelisted file names; renamed/moved log directories breaking assumptions.
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31).
Data as JSON: /api/errors/62c72ca6415ba043.
Report an issue: GitHub.