Skip to content
Snippets Groups Projects
Commit b816da37 authored by jonny's avatar jonny
Browse files

use url package for parsing of urls

parent cad0c8ac
No related branches found
No related tags found
1 merge request!6fixed url injection by means of starting an url with "." and turning the prefix into a subdomain
...@@ -44,7 +44,7 @@ import LintWriter (LintWriter, adjust, askContext, ...@@ -44,7 +44,7 @@ import LintWriter (LintWriter, adjust, askContext,
import Paths (PathResult (..), RelPath (..), getExtension, import Paths (PathResult (..), RelPath (..), getExtension,
isOldStyle, parsePath) isOldStyle, parsePath)
import Types (Dep (Link, Local, LocalMap, MapLink)) import Types (Dep (Link, Local, LocalMap, MapLink))
import Uris (SubstError (..), applySubsts, parseUri) import Uris (SubstError (..), applySubsts, parseUri, extractDomain)
...@@ -142,7 +142,7 @@ checkMapProperty p@(Property name _) = case name of ...@@ -142,7 +142,7 @@ checkMapProperty p@(Property name _) = case name of
-- scripts can be used by one map -- scripts can be used by one map
_ | T.toLower name == "script" -> _ | T.toLower name == "script" ->
unwrapString p $ \str -> unwrapString p $ \str ->
unless (("https://static.rc3.world/scripts" `isPrefixOf` str) && unless ((checkIsRc3Url str) &&
(not $ "/../" `isInfixOf` str) && (not $ "/../" `isInfixOf` str) &&
(not $ "%" `isInfixOf` str) && (not $ "%" `isInfixOf` str) &&
(not $ "@" `isInfixOf` str)) (not $ "@" `isInfixOf` str))
...@@ -338,6 +338,12 @@ checkObjectGroupProperty (Property name _) = case name of ...@@ -338,6 +338,12 @@ checkObjectGroupProperty (Property name _) = case name of
\not the object layer." \not the object layer."
_ -> warn $ "unknown property " <> prettyprint name <> " for objectgroup layers" _ -> warn $ "unknown property " <> prettyprint name <> " for objectgroup layers"
checkIsRc3Url :: Text -> Bool
checkIsRc3Url text= case extractDomain text of
Nothing -> False
Just domain -> do
domain == "https://static.rc3.world"
-- | Checks a single (custom) property of a "normal" tile layer -- | Checks a single (custom) property of a "normal" tile layer
checkTileLayerProperty :: Property -> LintWriter Layer checkTileLayerProperty :: Property -> LintWriter Layer
...@@ -480,7 +486,7 @@ checkTileLayerProperty p@(Property name _value) = case name of ...@@ -480,7 +486,7 @@ checkTileLayerProperty p@(Property name _value) = case name of
-> do -> do
properties <- askContext <&> getProperties properties <- askContext <&> getProperties
unless (all (\(Property name value) -> case value of unless (all (\(Property name value) -> case value of
StrProp str -> name /= "openWebsite" || "https://static.rc3.world/" `isPrefixOf` str StrProp str -> name /= "openWebsite" || checkIsRc3Url str
_ -> True _ -> True
) properties) ) properties)
$ complain "\"openWebsiteAllowApi\" can only be used with websites hosted \ $ complain "\"openWebsiteAllowApi\" can only be used with websites hosted \
......
...@@ -18,7 +18,7 @@ import Data.Data (Proxy) ...@@ -18,7 +18,7 @@ import Data.Data (Proxy)
import Data.Either.Combinators (maybeToRight, rightToMaybe) import Data.Either.Combinators (maybeToRight, rightToMaybe)
import Data.Map.Strict (Map) import Data.Map.Strict (Map)
import qualified Data.Map.Strict as M import qualified Data.Map.Strict as M
import Data.Text (Text, pack) import Data.Text (Text, pack, unpack)
import qualified Data.Text as T import qualified Data.Text as T
import GHC.Generics (Generic) import GHC.Generics (Generic)
import GHC.TypeLits (KnownSymbol, symbolVal) import GHC.TypeLits (KnownSymbol, symbolVal)
...@@ -26,6 +26,9 @@ import Text.Regex.TDFA ((=~)) ...@@ -26,6 +26,9 @@ import Text.Regex.TDFA ((=~))
import Witherable (mapMaybe) import Witherable (mapMaybe)
import Network.URI.Encode as URI import Network.URI.Encode as URI
import Network.URI as NativeUri
import Data.String
data Substitution = data Substitution =
Prefixed { prefix :: Text, blocked :: [Text], allowed :: [Text], scope :: [String] } Prefixed { prefix :: Text, blocked :: [Text], allowed :: [Text], scope :: [String] }
| DomainSubstitution { substs :: Map Text Text, scope :: [String] } | DomainSubstitution { substs :: Map Text Text, scope :: [String] }
...@@ -44,17 +47,26 @@ type SchemaSet = [(Text, Substitution)] ...@@ -44,17 +47,26 @@ type SchemaSet = [(Text, Substitution)]
extractDomain :: Text -> Maybe Text extractDomain :: Text -> Maybe Text
extractDomain url = extractDomain url =
let (_,_,_,matches) = url =~ "^https://([^/]+)/?.*$" :: (Text,Text,Text,[Text]) case parseUri url of
in case matches of Nothing -> Nothing
[domain] -> Just domain Just (_,domain,_) -> Just domain
_ -> Nothing
parseUri :: Text -> Maybe (Text, Text, Text) parseUri :: Text -> Maybe (Text, Text, Text)
parseUri uri = parseUri uri =
let (_,_,_,matches) = uri =~ "^([a-zA-Z0-9]+)://([^/]+)(/?.*)$" :: (Text,Text,Text,[Text]) case parseURI (unpack uri) of
in case matches of Nothing -> Nothing
[schema, domain, rest] -> Just (schema, domain, rest) Just parsedUri -> case uriAuthority parsedUri of
_ -> Nothing Nothing -> Nothing
-- https:
Just uriAuth -> Just (T.replace (fromString ":") (fromString "") (fromString (uriScheme parsedUri )),
-- //anonymous@ www.haskell.org :42
fromString(uriUserInfo uriAuth++uriRegName uriAuth ++ uriPort uriAuth),
-- /ghc ?query #frag
fromString(uriPath parsedUri ++ uriQuery parsedUri ++ uriFragment parsedUri))
data SubstError = data SubstError =
SchemaDoesNotExist Text SchemaDoesNotExist Text
......
...@@ -57,7 +57,8 @@ library ...@@ -57,7 +57,8 @@ library
witherable, witherable,
dotgen, dotgen,
text-metrics, text-metrics,
uri-encode uri-encode,
network-uri
-- TODO: move more stuff into lib, these dependencies are silly -- TODO: move more stuff into lib, these dependencies are silly
executable walint executable walint
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment