module Hadolint.Rule.DL3064 (rule) where import qualified Data.Text as Text import Hadolint.Rule import Hadolint.Shell (ParsedShell) import Language.Docker.Syntax rule :: Rule ParsedShell rule :: Rule ParsedShell rule = Rule ParsedShell dl3064 Rule ParsedShell -> Rule ParsedShell -> Rule ParsedShell forall a. Semigroup a => a -> a -> a <> Rule ParsedShell -> Rule ParsedShell forall args. Rule args -> Rule args onbuild Rule ParsedShell dl3064 {-# INLINEABLE rule #-} dl3064 :: Rule ParsedShell dl3064 :: Rule ParsedShell dl3064 = RuleCode -> DLSeverity -> Text -> (Instruction ParsedShell -> Bool) -> Rule ParsedShell forall args. RuleCode -> DLSeverity -> Text -> (Instruction args -> Bool) -> Rule args simpleRule RuleCode code DLSeverity severity Text message Instruction ParsedShell -> Bool forall {args}. Instruction args -> Bool check where code :: RuleCode code = RuleCode "DL3064" severity :: DLSeverity severity = DLSeverity DLWarningC message :: Text message = Text "Potentially sensitive data should not be used in the `ARG` or `ENV` commands" check :: Instruction args -> Bool check (Arg Text name Maybe Text _) = Text -> Text Text.toUpper Text name Text -> [Text] -> Bool forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool `notElem` [Text] knownSensitiveNames Bool -> Bool -> Bool && (Text -> Bool) -> [Text] -> Bool forall a. (a -> Bool) -> [a] -> Bool none (Text -> Text -> Bool `Text.isInfixOf` Text -> Text Text.toLower Text name) [Text] suspiciousSubstrings check (Env Pairs pairs) = ((Text, Text) -> Bool) -> Pairs -> Bool forall a. (a -> Bool) -> [a] -> Bool none (\(Text, Text) s -> (Text -> Text Text.toUpper (Text -> Text) -> ((Text, Text) -> Text) -> (Text, Text) -> Text forall b c a. (b -> c) -> (a -> b) -> a -> c . (Text, Text) -> Text forall a b. (a, b) -> a fst) (Text, Text) s Text -> [Text] -> Bool forall a. Eq a => a -> [a] -> Bool forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool `elem` [Text] knownSensitiveNames) Pairs pairs Bool -> Bool -> Bool && (Text -> Bool) -> [Text] -> Bool forall a. (a -> Bool) -> [a] -> Bool none (\Text s -> ((Text, Text) -> Bool) -> Pairs -> Bool forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool any ((Text s Text -> Text -> Bool `Text.isInfixOf`) (Text -> Bool) -> ((Text, Text) -> Text) -> (Text, Text) -> Bool forall b c a. (b -> c) -> (a -> b) -> a -> c . Text -> Text Text.toLower (Text -> Text) -> ((Text, Text) -> Text) -> (Text, Text) -> Text forall b c a. (b -> c) -> (a -> b) -> a -> c . (Text, Text) -> Text forall a b. (a, b) -> a fst) Pairs pairs) [Text] suspiciousSubstrings check Instruction args _ = Bool True {-# INLINEABLE dl3064 #-} none :: (a -> Bool) -> [a] -> Bool none :: forall a. (a -> Bool) -> [a] -> Bool none a -> Bool p [a] xs = Bool -> Bool not ( (a -> Bool) -> [a] -> Bool forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool any a -> Bool p [a] xs ) knownSensitiveNames :: [Text.Text] knownSensitiveNames :: [Text] knownSensitiveNames = [ Text "ACCESS_TOKEN", Text "APPLICATION_KEY", Text "APP_SECRET", Text "AUTH_TOKEN", Text "AWS_ACCESS_KEY_ID", Text "AWS_SECRET_ACCESS_KEY", Text "BITTREX_API_KEY", Text "BITTREX_API_SECRET", Text "CF_PASSWORD", Text "CF_USERNAME", Text "CIRCLE_TOKEN", Text "CI_DEPLOY_PASSWORD", Text "CI_DEPLOY_USER", Text "DOCKERHUB_PASSWORD", Text "DOCKER_EMAIL", Text "DOCKER_PASSWORD", Text "DOCKER_USERNAME", Text "FACEBOOK_ACCESS_TOKEN", Text "FACEBOOK_APP_ID", Text "FACEBOOK_APP_SECRET", Text "FIREBASE_API_TOKEN", Text "FIREBASE_TOKEN", Text "FOSSA_API_KEY", Text "GH_ENTERPRISE_TOKEN", Text "GH_TOKEN", Text "GITHUB_ENTERPRISE_TOKEN", Text "GITHUB_TOKEN", Text "HEROKU_API_KEY", Text "HEROKU_API_USER", Text "NPM_AUTH_TOKEN", Text "NPM_TOKEN", Text "OKTA_AUTHN_GROUPID", Text "OKTA_CLIENT_ORGURL", Text "OKTA_CLIENT_TOKEN", Text "OKTA_OAUTH2_CLIENTID", Text "OKTA_OAUTH2_CLIENTSECRET", Text "OPENAI_API_KEY", Text "OS_PASSWORD", Text "OS_USERNAME", Text "POSTGRES_PASSWORD", Text "SLACK_TOKEN", Text "STRIPE_API_KEY", Text "STRIPE_DEVICE_NAME", Text "TRAVIS_OS_NAME", Text "TRAVIS_SECURE_ENV_VARS", Text "TRAVIS_SUDO", Text "VAULT_CLIENT_KEY", Text "VAULT_TOKEN" ] suspiciousSubstrings :: [Text.Text] suspiciousSubstrings :: [Text] suspiciousSubstrings = [ Text "api_key", Text "client_key", Text "password", Text "private", Text "secret", Text "token", Text "username" ]