fix(DB): validates db name for path traversal
This commit is contained in:
parent
3e3c55d0b6
commit
e806bd9046
4 changed files with 45 additions and 2 deletions
|
|
@ -51,6 +51,9 @@ func ParseKey(raw string, defaults bool) (KeySpec, error) {
|
||||||
if strings.TrimSpace(rawDB) == "" {
|
if strings.TrimSpace(rawDB) == "" {
|
||||||
return KeySpec{}, fmt.Errorf("bad key format, use KEY@DB")
|
return KeySpec{}, fmt.Errorf("bad key format, use KEY@DB")
|
||||||
}
|
}
|
||||||
|
if err := validateDBName(rawDB); err != nil {
|
||||||
|
return KeySpec{}, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
key := strings.ToLower(rawKey)
|
key := strings.ToLower(rawKey)
|
||||||
|
|
|
||||||
|
|
@ -178,6 +178,9 @@ func (s *Store) parseDB(v string, defaults bool) (string, error) {
|
||||||
}
|
}
|
||||||
return "", fmt.Errorf("cannot parse db: bad db format, use DB or @DB")
|
return "", fmt.Errorf("cannot parse db: bad db format, use DB or @DB")
|
||||||
}
|
}
|
||||||
|
if err := validateDBName(db); err != nil {
|
||||||
|
return "", fmt.Errorf("cannot parse db: %w", err)
|
||||||
|
}
|
||||||
return strings.ToLower(db), nil
|
return strings.ToLower(db), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -197,7 +200,11 @@ func (s *Store) path(args ...string) (string, error) {
|
||||||
if err := os.MkdirAll(override, 0o750); err != nil {
|
if err := os.MkdirAll(override, 0o750); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return filepath.Join(append([]string{override}, args...)...), nil
|
target := filepath.Join(append([]string{override}, args...)...)
|
||||||
|
if err := ensureSubpath(override, target); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return target, nil
|
||||||
}
|
}
|
||||||
scope := gap.NewVendorScope(gap.User, "pda", "stores")
|
scope := gap.NewVendorScope(gap.User, "pda", "stores")
|
||||||
dir, err := scope.DataPath("")
|
dir, err := scope.DataPath("")
|
||||||
|
|
@ -207,7 +214,11 @@ func (s *Store) path(args ...string) (string, error) {
|
||||||
if err := os.MkdirAll(dir, 0o750); err != nil {
|
if err := os.MkdirAll(dir, 0o750); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return filepath.Join(append([]string{dir}, args...)...), nil
|
target := filepath.Join(append([]string{dir}, args...)...)
|
||||||
|
if err := ensureSubpath(dir, target); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return target, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) suggestStores(target string) ([]string, error) {
|
func (s *Store) suggestStores(target string) ([]string, error) {
|
||||||
|
|
@ -229,6 +240,33 @@ func (s *Store) suggestStores(target string) ([]string, error) {
|
||||||
return suggestions, nil
|
return suggestions, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ensureSubpath(base, target string) error {
|
||||||
|
absBase, err := filepath.Abs(base)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
absTarget, err := filepath.Abs(target)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
rel, err := filepath.Rel(absBase, absTarget)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
sep := string(filepath.Separator)
|
||||||
|
if rel == ".." || strings.HasPrefix(rel, ".."+sep) {
|
||||||
|
return fmt.Errorf("path escapes store root")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateDBName(name string) error {
|
||||||
|
if strings.ContainsAny(name, `/\`) {
|
||||||
|
return fmt.Errorf("bad db format, use DB or @DB")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func formatExpiry(expiresAt uint64) string {
|
func formatExpiry(expiresAt uint64) string {
|
||||||
if expiresAt == 0 {
|
if expiresAt == 0 {
|
||||||
return "never"
|
return "never"
|
||||||
|
|
|
||||||
1
main.go
1
main.go
|
|
@ -19,6 +19,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import "github.com/llywelwyn/pda/cmd"
|
import "github.com/llywelwyn/pda/cmd"
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue