<div id="docs-body">
 <div class="section">
  <div class="titlepage">
   <div>
    <div>
     <h3 class="title">
      <a name="security-guidelines">
      </a>
      8.1.1 Security Guidelines
     </h3>
    </div>
   </div>
  </div>
  <a class="indexterm" name="idm46045252947168">
  </a>
  <a class="indexterm" name="idm46045252946096">
  </a>
  <p>
   Anyone using MySQL on a computer connected to the Internet should
      read this section to avoid the most common security mistakes.
  </p>
  <p>
   In discussing security, it is necessary to consider fully
      protecting the entire server host (not just the MySQL server)
      against all types of applicable attacks: eavesdropping, altering,
      playback, and denial of service. We do not cover all aspects of
      availability and fault tolerance here.
  </p>
  <p>
   MySQL uses security based on Access Control Lists (ACLs) for all
      connections, queries, and other operations that users can attempt
      to perform. There is also support for SSL-encrypted connections
      between MySQL clients and servers. Many of the concepts discussed
      here are not specific to MySQL at all; the same general ideas
      apply to almost all applications.
  </p>
  <p>
   When running MySQL, follow these guidelines:
  </p>
  <div class="itemizedlist">
   <ul class="itemizedlist" style="list-style-type: disc; ">
    <li class="listitem">
     <p>
      <span class="bold">
       <strong>
        Do not ever give anyone (except MySQL
        <code class="literal">
         root
        </code>
        accounts) access to the
        <code class="literal">
         user
        </code>
        table in the
        <code class="literal">
         mysql
        </code>
        system database!
       </strong>
      </span>
      This is critical.
     </p>
    </li>
    <li class="listitem">
     <p>
      Learn how the MySQL access privilege system works (see
      <a class="xref" href="access-control.html" title="8.2 Access Control and Account Management">
       Section 8.2, “Access Control and Account Management”
      </a>
      ). Use the
      <a class="link" href="grant.html" title="15.7.1.6 GRANT Statement">
       <code class="literal">
        GRANT
       </code>
      </a>
      and
      <a class="link" href="revoke.html" title="15.7.1.8 REVOKE Statement">
       <code class="literal">
        REVOKE
       </code>
      </a>
      statements to control
          access to MySQL. Do not grant more privileges than necessary.
          Never grant privileges to all hosts.
     </p>
     <p>
      Checklist:
     </p>
     <div class="itemizedlist">
      <ul class="itemizedlist" style="list-style-type: circle; ">
       <li class="listitem">
        <p>
         Try
         <code class="literal">
          mysql -u root
         </code>
         . If you are able to
              connect successfully to the server without being asked for
              a password, anyone can connect to your MySQL server as the
              MySQL
         <code class="literal">
          root
         </code>
         user with full privileges!
              Review the MySQL installation instructions, paying
              particular attention to the information about setting a
         <code class="literal">
          root
         </code>
         password. See
         <a class="xref" href="default-privileges.html" title="2.9.4 Securing the Initial MySQL Account">
          Section 2.9.4, “Securing the Initial MySQL Account”
         </a>
         .
        </p>
       </li>
       <li class="listitem">
        <p>
         Use the
         <a class="link" href="show-grants.html" title="15.7.7.22 SHOW GRANTS Statement">
          <code class="literal">
           SHOW GRANTS
          </code>
         </a>
         statement to check which accounts have access to what.
              Then use the
         <a class="link" href="revoke.html" title="15.7.1.8 REVOKE Statement">
          <code class="literal">
           REVOKE
          </code>
         </a>
         statement to remove those privileges that are not
              necessary.
        </p>
       </li>
      </ul>
     </div>
    </li>
    <li class="listitem">
     <p>
      Do not store cleartext passwords in your database. If your
          computer becomes compromised, the intruder can take the full
          list of passwords and use them. Instead, use
      <a class="link" href="encryption-functions.html#function_sha2">
       <code class="literal">
        SHA2()
       </code>
      </a>
      or some other one-way
          hashing function and store the hash value.
     </p>
     <p>
      To prevent password recovery using rainbow tables, do not use
          these functions on a plain password; instead, choose some
          string to be used as a salt, and use hash(hash(password)+salt)
          values.
     </p>
    </li>
    <li class="listitem">
     <p>
      Assume that all passwords will be subject to automated
          cracking attempts using lists of known passwords, and also to
          targeted guessing using publicly available information about
          you, such as social media posts. Do not choose passwords that
          consist of easily cracked or guessed items such as a
          dictionary word, proper name, sports team name, acronym, or
          commonly known phrase, particularly if they are relevant to
          you. The use of upper case letters, number substitutions and
          additions, and special characters does not help if these are
          used in predictable ways. Also do not choose any password you
          have seen used as an example anywhere, or a variation on it,
          even if it was presented as an example of a strong password.
     </p>
     <p>
      Instead, choose passwords that are as long and as
          unpredictable as possible. That does not mean the combination
          needs to be a random string of characters that is difficult to
          remember and reproduce, although this is a good approach if
          you have, for example, password manager software that can
          generate and fill such passwords and store them securely. A
          passphrase containing multiple words is easy to create,
          remember, and reproduce, and is much more secure than a
          typical user-selected password consisting of a single modified
          word or a predictable sequence of characters. To create a
          secure passphrase, ensure that the words and other items in it
          are not a known phrase or quotation, do not occur in a
          predictable order, and preferably have no previous
          relationship to each other at all.
     </p>
    </li>
    <li class="listitem">
     <p>
      Invest in a firewall. This protects you from at least 50% of
          all types of exploits in any software. Put MySQL behind the
          firewall or in a demilitarized zone (DMZ).
     </p>
     <p>
      Checklist:
     </p>
     <div class="itemizedlist">
      <ul class="itemizedlist" style="list-style-type: circle; ">
       <li class="listitem">
        <p>
         Try to scan your ports from the Internet using a tool such
              as
         <code class="literal">
          nmap
         </code>
         . MySQL uses port 3306 by
              default. This port should not be accessible from untrusted
              hosts. As a simple way to check whether your MySQL port is
              open, try the following command from some remote machine,
              where
         <em class="replaceable">
          <code>
           server_host
          </code>
         </em>
         is the host
              name or IP address of the host on which your MySQL server
              runs:
        </p>
        <div class="copytoclipboard-wrapper">
         <pre class="programlisting one-line language-terminal"><div class="docs-select-all right" id="sa24074555"><div class="copy-help left">Press ⌘+C to copy</div> <div class="right"><button class="clipboard-btn" title="Copy to Clipboard"><span class="icon-clipboard"></span></button></div></div><code class="language-terminal"><span class="token prompt">$&gt; </span><span class="token command">telnet</span> <em class="replaceable">server_host</em> 3306</code></pre>
        </div>
        <p>
         If
         <span class="command">
          <strong>
           telnet
          </strong>
         </span>
         hangs or the connection is
              refused, the port is blocked, which is how you want it to
              be. If you get a connection and some garbage characters,
              the port is open, and should be closed on your firewall or
              router, unless you really have a good reason to keep it
              open.
        </p>
       </li>
      </ul>
     </div>
    </li>
    <li class="listitem">
     <p>
      Applications that access MySQL should not trust any data
          entered by users, and should be written using proper defensive
          programming techniques. See
      <a class="xref" href="secure-client-programming.html" title="8.1.7 Client Programming Security Guidelines">
       Section 8.1.7, “Client Programming Security Guidelines”
      </a>
      .
     </p>
    </li>
    <li class="listitem">
     <p>
      Do not transmit plain (unencrypted) data over the Internet.
          This information is accessible to everyone who has the time
          and ability to intercept it and use it for their own purposes.
          Instead, use an encrypted protocol such as SSL or SSH. MySQL
          supports internal SSL connections. Another technique is to use
          SSH port-forwarding to create an encrypted (and compressed)
          tunnel for the communication.
     </p>
    </li>
    <li class="listitem">
     <p>
      Learn to use the
      <span class="command">
       <strong>
        tcpdump
       </strong>
      </span>
      and
      <span class="command">
       <strong>
        strings
       </strong>
      </span>
      utilities. In most cases, you can
          check whether MySQL data streams are unencrypted by issuing a
          command like the following:
     </p>
     <div class="copytoclipboard-wrapper">
      <pre class="programlisting one-line language-terminal"><div class="docs-select-all right" id="sa30405908"><div class="copy-help left">Press ⌘+C to copy</div> <div class="right"><button class="clipboard-btn" title="Copy to Clipboard"><span class="icon-clipboard"></span></button></div></div><code class="language-terminal"><span class="token prompt">$&gt; </span><span class="token command">tcpdump</span> <span class="token property">-l</span> <span class="token property">-i</span> eth0 <span class="token property">-w</span> - src or dst port 3306 | strings</code></pre>
     </div>
     <p>
      This works under Linux and should work with small
          modifications under other systems.
     </p>
     <div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">
      <div class="admon-title">
       Warning
      </div>
      <p>
       If you do not see cleartext data, this does not always mean
            that the information actually is encrypted. If you need high
            security, consult with a security expert.
      </p>
     </div>
    </li>
   </ul>
  </div>
 </div>
 <br/>
</div>
