Merge branch 'master' of gitlab.science.ru.nl:mlubbers/ssproject1617
authorDaan Sprenkels <dsprenkels@gmail.com>
Wed, 16 Nov 2016 11:16:40 +0000 (12:16 +0100)
committerDaan Sprenkels <dsprenkels@gmail.com>
Wed, 16 Nov 2016 11:16:40 +0000 (12:16 +0100)
1  2 
report/preamble.tex
report/v11_httpsec.tex
report/v2_authentication.tex
report/v3_session.tex
report/v4_access.tex
report/v5_input.tex
report/v7_cryptography.tex

diff --combined report/preamble.tex
    innertopmargin=2pt,
    innerbottommargin=2pt,
    skipabove=\topsep,
-   skipbelow=\topsep
+   skipbelow=\topsep%
  ]{result}
  
  % Tools afkortingen
+ \newcommand{\API}{\emph{API}}
+ \newcommand{\CMS}{\emph{CMS}}
+ \newcommand{\CSRF}{\emph{CSRF}}
+ \newcommand{\DELETE}{\emph{DELETE}}
+ \newcommand{\DOM}{\emph{DOM}}
+ \newcommand{\GET}{\emph{GET}}
+ \newcommand{\GUID}{\emph{GUID}}
+ \newcommand{\HTMLF}{\textsc{HTML5}}
+ \newcommand{\HTML}{\textsc{HTML}}
+ \newcommand{\HTTPS}{\textsc{HTTPS}}
+ \newcommand{\HTTP}{\textsc{HTTP}}
+ \newcommand{\JQuery}{\textsc{JQuery}}
+ \newcommand{\JSON}{\textsc{JSON}}
+ \newcommand{\LDAP}{\textsc{LDAP}}
  \newcommand{\PHP}{\textsc{PHP}}
+ \newcommand{\PII}{\emph{PII}}
+ \newcommand{\POST}{\emph{POST}}
+ \newcommand{\PUT}{\emph{PUT}}
+ \newcommand{\REST}{\emph{REST}}
+ \newcommand{\RSS}{\emph{RSS}}
+ \newcommand{\SMTP}{\emph{SMTP}}
  \newcommand{\SQL}{\textsc{SQL}}
- \newcommand{\LDAP}{\textsc{LDAP}}
+ \newcommand{\SSO}{\emph{SSO}}
+ \newcommand{\TOTP}{\emph{TOTP}}
+ \newcommand{\TRACE}{\emph{TRACE}}
  \newcommand{\XML}{\textsc{XML}}
- \newcommand{\HTML}{\textsc{HTML}}
- \newcommand{\JSON}{\textsc{JSON}}
- \newcommand{\JQuery}{\textsc{JQuery}}
+ \newcommand{\XSS}{\emph{XSS}}
  
  % Reference naar de source
 -\newcommand{\srcref}[2]{{\small\texttt{#1}} (line (s) #2)}
 +\newcommand{\srcref}[2]{{\small\texttt{#1}} (line(s) #2)}
  
  % Pass en fail
  \newcommand{\pass}{{\large\ding{51}}}
diff --combined report/v11_httpsec.tex
@@@ -3,29 -3,29 +3,29 @@@
  
  \item\fail{}
  Verify that the application accepts only a defined
- set of required HTTP request methods, such as
GET and POST are accepted, and unused methods
- (e.g. TRACE, PUT, and DELETE) are explicitly
+ set of required \HTTP{} request methods, such as
\GET{} and \POST{} are accepted, and unused methods
+ (e.g. \TRACE{}, \PUT{}, and \DELETE{}) are explicitly
  blocked.
  \begin{result}
-     The application treats only \texttt{POST} requests as different from
+     The application treats only \POST{} requests as different from
      others and in an opportunistic manner. It assumes all other methods to be
-     treated as \texttt{GET} requests.
+       treated as \GET{} requests.
  \end{result}
  
  \item\pass{}
- Verify that every HTTP response contains a
+ Verify that every \HTTP{} response contains a
  content type header specifying a safe character set
- (e.g., UTF-8, ISO 8859-1).
+ (e.g., \emph{UTF-8}, \emph{ISO 8859{-}1}).
  \begin{result}
      Content type headers may be set anywhere in the application. Furthermure,
-     \texttt{Response::send} ensures that if no content type header is set, all
-     responses will fall back to using \texttt{text/html; charset=UTF-8}.
+     \code{Response::send} ensures that if no content type header is set, all
+     responses will fall back to using \code{text/html; charset=UTF-8}.
  \end{result}
  
  \notapplicable{\item
- Verify that HTTP headers added by a trusted proxy
- or SSO devices, such as a bearer token, are
+ Verify that \HTTP{} headers added by a trusted proxy
+ or \SSO{} devices, such as a bearer token, are
  authenticated by the application.}
  
  % No proxies are present
@@@ -35,31 -35,30 +35,31 @@@ Verify that a suitable X-FRAME-OPTIONS 
  in use for sites where content should not be
  viewed in a 3rd-party X-Frame.
  \begin{result}
-     The application will never supply an \texttt{X-FRAME-OPTIONS} header. While
+     The application will never supply an \code{X-FRAME-OPTIONS} header. While
      this is not really a problem for the home page, a 3rd party X-Frame should
 -    not be able to refer to the administrative interfaces of the application.
 +    not be able to refer to the administrative interfaces of the application
 +    and this should be fixed.
  \end{result}
  
  \item\pass{}
- Verify that the HTTP headers or any part of the
HTTP response do not expose detailed version
+ Verify that the \HTTP{} headers or any part of the
\HTTP{} response do not expose detailed version
  information of system components.
  \begin{result}
-     The headers provide information about the PHP version (these are added by
-     the PHP interpreter by default) and information about the webserver. This
+       The headers provide information about the \PHP{} version (these are added by
+       the \PHP{} interpreter by default) and information about the webserver. This
      information is not specific for the application. It would be advisable to
-     hide the PHP version to the client, but this is specific to the way the
+       hide the \PHP{} version to the client, but this is specific to the way the
      application is installed.
  \end{result}
  
  \item\fail{}
- Verify that all API responses contain X-Content-Type-Options:
- nosniff and Content-Disposition:
attachment; filename="api.json" (or other
+ Verify that all \API{} responses contain \code{X-Content-Type-Options:
+ nosniff} and\\
\code{Content-Disposition: attachment; filename="api.json"} (or other
  appropriate filename for the content type).
  \begin{result}
-     The application does not supply the \texttt{X-Content-Type-Options} header.
+     The application does not supply the \code{X-Content-Type-Options} header.
  \end{result}
  
  \item\fail{}
@@@ -72,10 -71,10 +72,10 @@@ JSON, and JavaScript injection vulnerab
  
  \item\fail{}
  Verify that the X-XSS-Protection: 1; mode=block
- header is in place to enable browser reflected XSS
+ header is in place to enable browser reflected \XSS{}
  filters.
  \begin{result}
-     The application does not supply the \texttt{X-XSS-Protection} header.
+     The application does not supply the \code{X-XSS-Protection} header.
  \end{result}
  
  \end{enumerate}
@@@ -48,10 -48,10 +48,10 @@@ attackers cannot log in
  
  \begin{result}
      The input to various forms is not sanitized at all. This makes the implementation
-     in (not only) \texttt{Users::find} vulnerable to SQL injections. The login form
-     is also vulnerable. Any user can execute arbitrary SQL code from the username field.
+     in (not only) \code{Users::find} vulnerable to \SQL{} injections. The login form
+     is also vulnerable. Any user can execute arbitrary \SQL{} code from the username field.
      The following example code can submitted as username in the login form, which
-     will set the password of the \texttt{admin} user to \texttt{s3cret}:
+     will set the password of the \code{admin} user to \code{s3cret}:
  
      \code{"; UPDATE users SET password='\$1\$OWgsBb90\$Lkko6aZwmp9XOVrFI09Ab0' WHERE \\username='admin' AND 'a' = "a}
  
@@@ -67,7 -67,7 +67,7 @@@ entered
  
  \begin{result}
      The application allows the user to use any password (except ones that contain
-     SQL code).
+       \SQL{} code).
  \end{result}
  
  \item
@@@ -89,7 -89,7 +89,7 @@@ authentication mechanism
      expire, however. It would be even better to require that a token be used
      withing a day (or so) after creation.
  
-     The security of the SMTP connection is at the discretion of the web server.
+       The security of the \SMTP{} connection is at the discretion of the web server.
      Often these connections are not very secure, but this worry is beyond the
      scope of this audit.
  \end{result}
@@@ -126,11 -126,11 +126,11 @@@ salt, and there is sufficient work fact
  force and password hash recovery attacks.
  
  \begin{result}
-     Password are stored in database using the PHP function \texttt{crypt}. Internally, this
-     function uses salted MD5. This is way easy too reverse with brute-force attacks using dictionary files.
+       Password are stored in database using the \PHP{} function \code{crypt}. Internally, this
+     function uses salted MD5. This is way too reverse with brute-force attacks using dictionary files.
  
-     Instead it would be better to use the \texttt{argon2} password hashing algorithm
-     or the PHP \texttt{password\_hash} function (which currently uses BCRYPT).
+     Instead it would be better to use the \code{argon2} password hashing algorithm
+       or the \PHP{} \code{password\_hash} function (which currently uses BCRYPT).
  \end{result}
  
  \setcounter{enumi}{15}
@@@ -143,9 -143,9 +143,9 @@@ user to enter credentials are done so u
  link.
  
  \begin{result}
-     The app allows admin users to log in over HTTP. This is insecure, as it allows
+       The app allows admin users to log in over \HTTP{}. This is insecure, as it allows
      eavesdroppers to intercept password.
-     The app should force HTTPS for at least the login form, the \texttt{admin\_controller} and
+       The app should force \HTTPS{} for at least the login form, the \code{admin\_controller} and
      for the installation script (because the users posts secrets like the database
      password to this page).
  \end{result}
@@@ -169,7 -169,7 +169,7 @@@ Verify that information enumeration is 
  login, password reset, or forgot account functionality.
  
  \begin{result}
-     All these forms are vulnerable to SQL injection attacks. So any information
+     All these forms are vulnerable to \SQL{} injection attacks. So any information
      can leak any information from the database.
  \end{result}
  
@@@ -181,7 -181,7 +181,7 @@@ application (such as â\80\9cadmin/passwordâ
  
  \begin{result}
      No secrets are initialized by predefined values. The admin user will have
-     username \texttt{admin} by default. This is no secret and therefore not
+     username \code{admin} by default. This is no secret and therefore not
      considered unsafe.
  \end{result}
  
@@@ -199,8 -199,7 +199,8 @@@ attacks
          \item Email validation, to harden brute force email address discovery
          \item Installation database check, to prevent guessing attacks for the database password
          \item Login, to prevent login guessing
 -        \item And comment submission, to prevent spam, phishing et cetera (by using CAPTCHA).
 +        \item And comment submission, to prevent spam, phishing et cetera (by
 +        using some CAPTCHA software).
      \end{itemize}
  \end{result}
  
@@@ -211,7 -210,7 +211,7 @@@ services external to the application ar
  stored in a protected location.
  
  \begin{result}
-     The database credentials are hardcoded in \texttt{config.php}. While it
+     The database credentials are hardcoded in \code{config.php}. While it
      would be better to pass secrets as environment variables, this is not
      really bad practice.
  
@@@ -222,13 -221,13 +222,13 @@@ you extracted testcms to
      \end{verbatim}
      This implies making the configuration file readable for all users on the
      system. This information should not be accessible for any user other than
-     the one running the PHP script.
+       running the \PHP{} script.
  \end{result}
  
  \item
  \pass{}
  Verify that forgotten password and other recovery paths
- use a TOTP or other soft token, mobile push, or other
+ use a \TOTP{} or other soft token, mobile push, or other
  offline recovery mechanism. Use of a random value in an
  e-mail or SMS should be a last resort and is known weak.
  
@@@ -248,7 -247,7 +248,7 @@@ attack, this should not reset the hard 
  
  \notapplicable{\item
  Verify that if shared knowledge based questions (also
- known as "secret questions") are required, the questions
+ known as ``secret questions'') are required, the questions
  do not violate privacy laws and are sufficiently strong to
  protect accounts from malicious recovery.}
  
@@@ -276,7 -275,7 +276,7 @@@ commonly chosen passwords and weak pass
  
  \begin{result}
      No password strengthening measures are implemented. The app should
 -    use some password strength estimator like \code{zxcvbn}.
 +    use some password strength estimator like \texttt{zxcvbn}\footnote{\url{https://github.com/dropbox/zxcvbn}}.
  \end{result}
  
  \item
@@@ -292,12 -291,12 +292,12 @@@ response time
  
  \item
  \fail{}
- Verify that secrets, API keys, and passwords are not
+ Verify that secrets, \API{} keys, and passwords are not
  included in the source code, or online source code
  repositories.
  
  \begin{result}
-     The database credentials are hard coded in \texttt{config.php}. These
+     The database credentials are hard coded in \code{config.php}. These
      credentials should ideally be passed using environment variables.
  \end{result}
  
diff --combined report/v3_session.tex
@@@ -40,7 -40,7 +40,7 @@@
      \begin{result}
      The logout functionality is plainly visible on the top right of the
        application on every page that requires authentication. This is defined in
-       \srcref{admin/themes/header.php}{16-30}
+               \srcref{admin/themes/header.php}{16{-}30}
      \end{result}
  
  
@@@ -91,7 -91,7 +91,7 @@@
      session tokens additionally set the “HttpOnly” and “secure” attributes.
      \begin{result}
      There is just one cookie for tha application and it's path includes the whole
-       site. However this seems appropriate. The "HttpOnly" and "secure"
+       site. However this seems appropriate. The ``HttpOnly'' and ``secure''
        attributes are not set for this cookie.
      \end{result}
  
      Verify the user is prompted with the option to terminate all other active
      sessions after a successful change password process.
      \begin{result}
 -    There is no such option, also notqeable is that there is no confirmation for
 +    There is no such option, also notaeable is that there is no confirmation for
        the password change.
      \end{result}
  
diff --combined report/v4_access.tex
@@@ -1,6 -1,6 +1,6 @@@
  
  \noindent
- The CMS has the following access control mechanisms:
+ The \CMS{} has the following access control mechanisms:
  
  \begin{itemize}
    \item A login mechanism, where logged in users are allowed to access the backend, and anonymous users are not.
@@@ -35,7 -35,7 +35,7 @@@ These are the results of our check
  
  \item
  \fail{}
- Verify that the principle of least privilege exists - users
+ Verify that the principle of least privilege exists {-} users
  should only be able to access functions, data files, URLs,
  controllers, services, and other resources, for which they
  possess specific authorization. This implies protection
@@@ -56,7 -56,9 +56,9 @@@ user (for example, protect against user
  parameter to see or alter another user's account).
  
  \begin{result}
- There is no different access context for distinct users. In particular, they are allowed to access and edit each others' account info, including password. Taken one way, this could be said to be by design and thus OK. But in any reasonable design concept allowing for distinct user accounts, this is clearly not the desired setup.
+ There is no different access context for distinct users. In particular, they
+       are allowed to access and edit each others' account info, including
+       password. Taken one way, this could be said to be by design and thus OK\. But in any reasonable design concept allowing for distinct user accounts, this is clearly not the desired setup.
  \end{result}
  
  \item
@@@ -69,7 -71,7 +71,7 @@@ such as \code{Thumbs.db}, \code{.DS\_St
  \begin{result}
  \begin{itemize}[leftmargin=*]
    \item \code{.gitignore} accessible, as well as any other dot-preceded file (except \code{.htaccess} itself by default Apache rules), as well as files such as \code{Thumbs.db} and \code{.DS\_Store}.
-   \item Directory contents were listed in my simple setup. A global apache setting may disable by default, but the \code{.htaccess} file doesn't explicitly disable (with \code{Options -Indexes}), so that the CMS's codebase basically enables the listing by default.
+   \item Directory contents were listed in my simple setup. A global apache setting may disable by default, but the \code{.htaccess} file doesn't explicitly disable (with \code{Options -Indexes}), so that the \CMS{}'s codebase basically enables the listing by default.
  \end{itemize}
  \end{result}
  
@@@ -92,15 -94,13 +94,15 @@@ Fail, because the role and distinct use
  \end{result}
  
  \item
 -\pass{}
 +\fail{}
  Verify that all user and data attributes and policy
  information used by access controls cannot be
  manipulated by end users unless specifically authorized.
  
  \begin{result}
 -This item is the main remaining security concern. I haven't found any obvious fail in the login system, but given the architecture and security status of the whole \CMS{}, I'm not very sure of it.
 +This item is the main remaining security concern, as the login form allows SQL
 +injections that are capable to alter any information stored in the database.
 +This is described in more detail in item V2.6 on page~\pageref{auth:6}.
  \end{result}
  
  \notapplicable{
@@@ -122,7 -122,7 +124,7 @@@ No such decision logging present. Ther
  \item
  \fail{}
  Verify that the application or framework uses strong
- random anti-CSRF tokens or has another transaction
+ random anti-\CSRF{} tokens or has another transaction
  protection mechanism.
  
  \begin{result}
diff --combined report/v5_input.tex
@@@ -11,7 -11,7 +11,7 @@@
  
        % They skip 5.2
        \addtocounter{enumi}{1}
 -      \item\fail{} Verify that server side input validation failures result in 
 +      \item\fail{} Verify that server side input validation failures result in
                request rejection and are logged.
  
                \begin{result}
@@@ -45,8 -45,8 +45,8 @@@
                \srcref{classes/users.php}{145}.
                \end{result}
  
-       \item\pass{} Verify that the application is not susceptible to LDAP
-               Injection, or that security controls prevent LDAP Injection.
+       \item\pass{} Verify that the application is not susceptible to \LDAP{}
+               Injection, or that security controls prevent \LDAP{} Injection.
  
                \begin{result}
                \LDAP{} is not used, thus the application is not susceptible.
                recovery\\
                (\srcref{classes/user.php}{115}) filepaths are calculated on the
                hash of the password. All non standard filepaths, such as admin or
-               theme files, are generated using functions. CMS urls are parsed using a
+               theme files, are generated using functions. \CMS{} urls are parsed using a
                standard system wide \code{parse} function.
                \end{result}
  
        \item\pass{} Verify that the application is not susceptible to common
                \XML{} attacks, such as XPath query tampering, \XML{} External Entity
 -              attacks, and \XML{} injection attacks. 
 +              attacks, and \XML{} injection attacks.
  
                \begin{result}
                No \XML{} or related techniques are used and thus the application is
                web client code is either properly contextually encoded manually, or
                utilize templates that automatically encode contextually to ensure the
                application is not susceptible to reflected, stored and DOM Cross-Site
-               Scripting (XSS) attacks.
+               Scripting (\XSS{}) attacks.
  
                \begin{result}
-               A lot of \HTML{} tags are allowed in the post screen, therefore an XSS
+               A lot of \HTML{} tags are allowed in the post screen, therefore an \XSS{}
                attack is trivial. Even the comment section uses no input validation
                whatsoever.
                \end{result}
                malicious automatic binding.
  
                \begin{result}
-               There is some automatic variable binding happening in the POST and GET
+               There is some automatic variable binding happening in the \POST{} and \GET{}
                however, defaults are always given and there is no possibility of
                accidentally binding extra variables. Also the variables are in an
                array.
                \end{result}
  
-       \item\pass{} Verify that the application has defenses against HTTP
+       \item\pass{} Verify that the application has defenses against \HTTP{}
                parameter pollution attacks, particularly if the application framework
-               makes no distinction about the source of request parameters (GET, POST,
+               makes no distinction about the source of request parameters (\GET{}, \POST{},
                cookies, headers, environment, etc.)
  
                \begin{result}
                \end{result}
  
        \item\fail{} Verify that all input data is validated, not only \HTML{} form
-               fields but all sources of input such as REST calls, query parameters,
-               HTTP headers, cookies, batch files, RSS feeds, etc; using positive
+               fields but all sources of input such as \REST{} calls, query parameters,
+               \HTTP{} headers, cookies, batch files, \RSS{} feeds, etc; using positive
                validation (whitelisting), then lesser forms of validation such as
                greylisting (eliminating known bad strings), or rejecting bad inputs
                (blacklisting).
  
                \begin{result}
-               REST calls are validated using whitelisting, query parameters are not,
+               \REST{} calls are validated using whitelisting, query parameters are not,
                headers are not, cookies not, batch files are non-existent and RSS feed
                output is not filtered.
                \end{result}
                against a defined schema including allowed characters, length and
                pattern (e.g.\  credit card numbers or telephone, or validating that two
                related fields are reasonable, such as validating suburbs and zip or
 -              post codes match). 
 +              post codes match).
  
                \begin{result}
                Email addresses are validated against \PHP's stander functionality.
                \begin{CJK}{UTF8}{min}ねこ\end{CJK} or O'Hara)
  
                \begin{result}
 -              Emailaddresses with non-ASCII characters are rejected. Unicode
 +              Email addresses with non-ASCII characters are rejected. Unicode
                characters are displayed correctly.
                \end{result}
  
        \item\fail{} Make sure untrusted \HTML{} from WYSIWYG editors or similar are
                properly sanitized with an \HTML{} sanitizer and handle it
 -              appropriately according to the input validation task and encoding task. 
 +              appropriately according to the input validation task and encoding task.
  
                \begin{result}
                This is not the case, any \HTML{} is allowed.
                ensure that \HTML{} sanitization is enabled instead.
  
                \begin{result}
 -              See previous item.
 +              Just as with the previous item, any \HTML{} is allowed.
                \end{result}
  
        \item\pass{} Verify that data transferred from one DOM context to another,
    \addtocounter{enumi}{3}
    \notapplicable{
      \item
-     Verify that all random numbers, random file names, random GUIDs, and random
+     Verify that all random numbers, random file names, random \GUID{}s, and random
      strings are generated using the cryptographic module’s approved random
      number generator when these random values are intended to be not guessable
      by an attacker.
    }
  
      \item
 -    \TODO{}
      Verify that cryptographic algorithms used by the application have been
-     validated against FIPS 140-2 or an equivalent standard.
+     validated against FIPS 140{-}2 or an equivalent standard.
      \begin{result}
 -    The application uses md-5 for password hashing, which should be insecure by
 +    The application uses MD5 for password hashing, which should be insecure by
        now.
      \end{result}
  
      Verify that sensitive passwords or key material maintained in memory is
      overwritten with zeros as soon as it no longer required, to mitigate memory
      dumping attacks.
 +    % FIXME(dsprenkels) Passwords should be zero'd?
    }
  
    \notapplicable{
      \item
      Verify that all keys and passwords are replaceable, and are generated or
      replaced at installation time.
 +    % FIXME(dsprenkels) This *is* relevant (passwords)
    }
  
    \notapplicable{
@@@ -77,8 -76,6 +77,8 @@@
      Verify that random numbers are created with proper entropy even when the
      application is under heavy load, or that the application degrades gracefully
      in such circumstance.
 +    % FIXME(dsprenkels) This *is* relevant: password generation of the admin
 +    %                   password in the install script uses a Mersenne twister!
    }
  
  \end{enumerate}