Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Odd behaviour with static policy using addBase #63

Closed
hdgarrood opened this issue Dec 24, 2013 · 8 comments
Closed

Odd behaviour with static policy using addBase #63

hdgarrood opened this issue Dec 24, 2013 · 8 comments

Comments

@hdgarrood
Copy link

I wanted to serve static files from src/static, under /static (so GET /static/some-file would look for src/static/some-file), so I did this:

let p = noDots >-> hasPrefix "/static" >-> addBase "src"
staticPolicy p

This didn't quite do what I expected:

tryPolicy p "/static/some-file" == Just "/static/some-file"

I think it's because of </> in System.FilePath; it seems it just returns the second argument if it starts with a slash:

"src" </> "/static/some-file" == "/static/some-file"

However curl and firefox both seem to always add this leading slash in the request URI.

Should addBase use ++ rather than FP.</>?

@hdgarrood
Copy link
Author

Actually, come to think of it, maybe it would work better to redo policies so that they expect the request URI as a [Text] rather than String. That way, it removes the need for addSlash (and any other gotchas involving leading/trailing slashes), and it makes it easy to pattern match:

findStaticFile :: [Text] -> Maybe [Text]
findStaticFile ("static":xs) = Just $ "src":xs
findStaticFile _             = Nothing

myPolicy :: Policy
myPolicy = noDots >-> policy findStaticFile

Then wai-middleware-static could do T.unpack . T.intercalate "/" at the end to get the filepath.

@daapp
Copy link

daapp commented Jan 8, 2014

addBase is insecure, if you do:
curl -i http://scottystarter.herokuapp.com///etc/passwd
you will see someones passwd file

My version of this code is:

import System.FilePath (isAbsolute)

addSecureBase :: String -> Policy
addSecureBase b = policy (\path -> if isAbsolute path then Nothing else Just (b </> path))

But addBase may be usefull for some cases.

@hdgarrood
Copy link
Author

I worked out why my code wasn't working; you just need to not include the leading slash in the addBase:

addBase "static"

@daapp raises a good point. I've just reproduced it locally:

scotty 3000 $ middleware (staticPolicy $ addBase "src")

Then curl localhost:3000//etc/passwd will print out the contents of /etc/passwd.

@co-dan
Copy link
Contributor

co-dan commented Jan 8, 2014

@daapp wow, this is really bad. I think your addSecureBase should be a default implementation.

@co-dan
Copy link
Contributor

co-dan commented Jan 8, 2014

@xich, what do you think about that?

@daapp
Copy link

daapp commented Jan 8, 2014

@co-dan I also recommend to add noDots to default implementation too. But also leave the way to ignore all these security locks.

@xich
Copy link
Member

xich commented Jan 27, 2014

Ugh, thanks for pointing this out... I'll work on fixing this, though patches are welcome! ;-)

nhibberd added a commit to nhibberd/scotty that referenced this issue Mar 24, 2014
These changes affect the security defaults and will definitely provide better behaviour for the existing users.
Issue scotty-web#64 - Implementating noDots by default.
Issue scotty-web#63 - Implementating isNotAbsolute by default tightens up the security to a normal standard.
nhibberd added a commit to nhibberd/scotty that referenced this issue Mar 24, 2014
These changes affect the security defaults and will definitely provide better behaviour for the existing users.
Issue scotty-web#64 - Implementating noDots by default.
Issue scotty-web#63 - Implementating isNotAbsolute by default tightens up the security to a normal standard.

Previous request on `localhost:3000//etc/passwd` would print out the contents of `/etc/passwd`. With the added security, the request will now return 404.
@xich
Copy link
Member

xich commented Mar 24, 2014

Merged and released as wai-middleware-static 0.5.0.0. Thanks for the patch @nhibberd

This should fix the absolute path issue (to /etc/passwd for example), but I'm leaving this issue open for now because I think @hdgarrood was right in that policies should work over [Text] (or [ByteString]) rather than String, to keep separators abstract.

Also, if anyone finds other gaping security problems, with wai-middleware-static or scotty itself, please let me know!

hdgarrood referenced this issue in purescript/pursuit Jul 3, 2015
Still to do:

* Make available versions for a package available as JSON
* Amend the version selector so that available versions are loaded via
  AJAX (so that the HTML doesn't need to change)
* Do something about the message for successfully uploaded packages
xich pushed a commit that referenced this issue Sep 18, 2015
These changes affect the security defaults and will definitely provide better behaviour for the existing users.
Issue #64 - Implementating noDots by default.
Issue #63 - Implementating isNotAbsolute by default tightens up the security to a normal standard.

Previous request on `localhost:3000//etc/passwd` would print out the contents of `/etc/passwd`. With the added security, the request will now return 404.
@chessai chessai closed this as completed Nov 13, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants