Page 1 of 3 123 Last
  • Jump to page:
    #1
  1. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,959
    Rep Power
    1014

    The 6 worst sins of security


    Hi,

    since certain security vulnerabilities are so common that you have to start almost every reply with the same warnings and explanations, I thought it makes sense to collect all the info in a kind of ďFAQĒ.

    The links below point directly to the particular issues, so you can use them in your replies if you want to.

    Feedback would be great! Iíll happily rectify my mistakes.


    This is not a tutorial on web security, because it doesnít cover things like file permissions or configuring the webserver. Itís only a list of common mistakes within PHP code. For more detailed and comprehensive info, check the OWASP.


    1. Donít insert raw values into query strings.

    2. Donít output raw values or insert them into the HTML page.

    3. Donít display internal error messages.

    4. Donít store passwords as plaintext or weak hashes (MD5, SHA-2 etc.).

    5. Donít allow actions solely based on the login status.

    6. Donít use weak random numbers for critical procedures.

    Comments on this post

    • TinaO agrees
    • requinix agrees
    • NotionCommotion agrees
    • iforwms agrees : Great post, learnt a lot. Thanks!
    Last edited by Jacques1; February 1st, 2013 at 05:06 PM.
  2. #2
  3. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,959
    Rep Power
    1014
    1. Donít insert raw values into query strings.

    If you build query strings from SQL commands and raw user input, attackers can manipulate the queries in order to fetch or change critical data or even access the underlying server (see SQL injection).


    What you should not do:

    Have a look at the following code, which is supposed to display blog entries of a certain category specified by a URL parameter:
    PHP Code:
    // don't use this

    $cat_id $_GET['cat_id'];

    $entries_query mysql_query("
        SELECT
            entry_id
            , title
            , entry_text
        FROM
            blog_entries
        WHERE
            category = '
    $cat_id'    -- Bad idea! cat_id could contain malicious SQL code
    "
    );
    if (
    $entries_query) {
        while (
    $blog_entry mysql_fetch_assoc($entries_query)) {
            
    // display $blog_entry
        
    }

    Since the literal content of cat_id gets inserted into the query string, this can be used to inject the following SQL code and change the original query:
    Code:
    '
    UNION
    SELECT
        user_id
        , email_address
        , password_hash
    FROM
        users
    --
    The resulting query will then display all user passwords instead of the blog entries:
    Code:
    SELECT
        entry_id
        , title
        , entry_text
    FROM
        blog_entries
    WHERE
        category = ''
    UNION
    SELECT
        user_id
        , email_address
        , password_hash
    FROM
        users
    -- '
    Note that this is a naive and relatively ďharmlessĒ example. Actual SQL injections can be much more sophisticated and might compromise the whole server. So itís very important to protect your application against those kinds of attacks, even if youíre not dealing with critical data.


    What you should do:

    The safest and most foolproof way of preventing SQL injections is to use prepared statements. A prepared statement is a kind of query template with parameters, which allows you to safely pass values to the query.

    Prepared statements are available through any of the new database extensions. The old MySQL extension (mysql_connect, mysql_query etc.) does not support prepared statements. But since itís deprecated, it shouldnít be used for new projects, anyway. If you have to use the old extension because of legacy code or an outdated PHP version, check the fallback below.

    Using the PDO interface and prepared statements, a secure version of the above code might look like this:

    database.inc.php
    PHP Code:
    $db_options = array(
        
    PDO::ATTR_EMULATE_PREPARES => false                     // important! use actual prepared statements (default: emulate prepared statements)
        
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION           // throw exceptions on errors (default: stay silent)
        
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC      // fetch associative arrays (default: mixed arrays)
    );
    $database = new PDO('mysql:host=localhost;dbname=YOURDB;charset=utf8''YOURUSER''YOURPW'$db_options);    // important! specify the character encoding in the DSN string, don't use SET NAMES 
    PHP Code:
    require_once dirname(__FILE__) . '/inc/database.inc.php';    // change this to actual location


    $cat_id $_GET['cat_id'];

    // create prepared statement with one parameter for the category ID
    $entries_stmt $database->prepare('
        SELECT
            entry_id
            , title
            , entry_text
        FROM
            blog_entries
        WHERE
            category = :cat_id
    '
    );
    // pass value to the prepared statement and execute it
    $entries_stmt->execute(array(
        
    ':cat_id' => $cat_id
    ));
    // fetch rows
    foreach ($entries_stmt as $blog_entry) {
        
    // display $blog_entry

    Note: Itís important to specify the character encoding in the DSN string (the first argument when creating a new PDO instance). Do not query the database with SET NAMES, because PDOís quote method wonít be aware of the new character encoding. In some cases, this can be used to bypass the whole escaping mechanism. Also make sure to set PDO::ATTR_EMULATE_PREPARES to false. Otherwise, PDO will use emulated prepared statements, which are subject to the same issues like the quote method.


    What you might use as a fallback:

    If you have a lot of old code and no chance to switch to the new database extensions, you have to escape every value ďby handĒ with mysql_real_escape_string and then wrap it in quotes:

    database.inc.php
    PHP Code:
    mysql_connect('localhost''YOURUSER''YOURPW');
    mysql_select_db('YOURDB');
    mysql_set_charset('utf8');      // important! don't use SET NAMES to specify the character encoding 
    functions.inc.php
    PHP Code:
    function mysql_value($raw_input) {
        return 
    "'" mysql_real_escape_string($raw_input) . "'";

    PHP Code:
    require_once dirname(__FILE__) . '/inc/database.inc.php';     // change this to actual location
    require_once dirname(__FILE__) . '/inc/functions.inc.php';    // change this to actual location


    $cat_id $_GET['cat_id'];

    $entries_query mysql_query('
        SELECT
            entry_id
            , title
            , entry_text
        FROM
            blog_entries
        WHERE
            category = ' 
    mysql_value($cat_id) . '
    '
    );
    if (
    $entries_query) {
        while (
    $blog_entry mysql_fetch_assoc($entries_query)) {
            
    // display $blog_entry
        
    }

    The escaping ensures that the input is ďtrappedĒ inside the quoted value and wonít be interpreted as SQL. Donít forget the quotes! If you do, the escaping will be useless.

    Since this approach is very tedious and error-prone, it should really just be used as a workaround for legacy code. In any other case, use prepared statements instead.

    Itís important to set the character encoding with mysql_set_charset. Do not query the database with SET NAMES, because this will render the escaping useless in some cases.

    Also be aware that the addslashes function does not reliably escape strings, because it only works with ASCII compatible encodings. So always use mysql_real_escape_string.

    Comments on this post

    • Frank Grimes agrees : Amazing how so few tutorials use PDO
    Last edited by Jacques1; January 30th, 2013 at 04:28 AM.
  4. #3
  5. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,959
    Rep Power
    1014
    2. Donít output raw values or insert them into the HTML page.

    Outputting raw variables allows attackers to inject JavaScript code into the page. This can be used to fetch data (like the cookies) from any visitor, take actions on behalf of another user, manipulate the page etc. (see cross-site scripting).


    What you should not do:

    Check the following code, which is supposed to display user comments on a blog post:
    PHP Code:
    // don't use this

    echo '<h2>comments</h2>';
    foreach (
    $blog_comments as $comment) {
        echo 
    "<p>{$comment['text']}</p>";    // bad idea! $comment['text'] could contain malicious HTML

    Since the comments donít get filtered in any way, their content will be interpreted as part of the HTML markup. An attacker can use this to inject the following JavaScript code into the page, which could steal the cookies from anybody visiting this page:
    Code:
    <script type="text/javascript">
        alert( "I just fetched your cookies: " + document.cookie );
    </script>

    What you should do:

    Escape every value with htmlspecialchars before outputting it. This will replace ďdangerousĒ characters like < or " with HTML entities, so that theyíre interpreted as literal characters rather than HTML markup:

    functions.inc.php
    PHP Code:
    function html_escape($raw_input) {
        return 
    htmlspecialchars($raw_inputENT_QUOTES ENT_HTML401'UTF-8');     // important! don't forget to specify ENT_QUOTES and the correct encoding

    PHP Code:
    require_once dirname(__FILE__) . '/inc/functions.inc.php';    // change this to actual location


    echo '<h2>comments</h2>';
    foreach (
    $blog_comments as $comment) {
        echo 
    '<p>' html_escape($comment['text']) . '</p>';

    Make sure to specify the correct character encoding when calling htmlspecialchars. It has to match the encoding of the page. If it doesnít, this can be used to circumvent the escaping in certain cases.

    Itís also important to specify the ENT_QUOTES flag in order to escape both double and single quotes.

    Be aware that HTML escaping has no effect when you insert a value into an existing JavaScript context (like a script element or an onclick attribute). Avoid this if possible. Otherwise, restrict the input to digits or use json_encode to generate a single JavaScript literal.
  6. #4
  7. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,959
    Rep Power
    1014
    3. Donít display internal error messages.

    Automatically generated error messages often contain critical information like queries, file paths or even login data, so they can be misused to prepare or optimize attacks. Apart from the security aspect, those messages also tend to irritate legitimate users.


    What you should not do:

    Many bad online tutorials and books suggest the following code to handle MySQL errors:
    PHP Code:
    // don't use this

    $users_query mysql_query('
        SELECT
            user_id
            , email_address
        FROM
            users
    '
    ) or die(mysql_error());    // bad idea! the error message shouldn't be seen by users 
    In case of an error, this will display the exact message from MySQL on the page, exposing internal information about your queries and your database structure.


    What you should do:

    Never output internal error messages by using die, echo, print etc., not even during development. If you need to generate error messages for debugging, call trigger_error or throw an exception, because those can be turned off later, redirected to a log file etc.:
    PHP Code:
    $users_query mysql_query('
        SELECT
            user_id
            , email_address
        FROM
            users
    '
    );
    if (!
    $users_query) {
        
    trigger_error('Query failed: ' mysql_error()  , E_USER_WARNING);

    On your public webserver, make sure to suppress all internal error messages by setting display_errors to Off in your php.ini. If you want to keep track of errors while the site is online, write them to a log file by setting log_errors and error_log appropriately. The log file must not be publicly accessible, of course.
    Last edited by Jacques1; February 1st, 2013 at 05:27 PM.
  8. #5
  9. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,959
    Rep Power
    1014
    4. Donít store passwords as plaintext or weak hashes (MD5, SHA-2 etc.).

    Never store plaintext passwords. Any vulnerability in your application could expose them immediately. And since many people reuse their passwords on different sites, this can have severe consequences not just for your own system.

    Standard hashing algorithms like MD5 or SHA-2, while certainly better than plaintext passwords, also donít provide sufficient security. Current CPUs and GPUs can calculate billions of MD5 hashes in a second, so many passwords can be retrieved by simply trying out all possible combinations. Since each string has a particular MD5 hash, itís also possible to precalculate the hashes of typical passwords and use this to look up matching strings for a given hash (see rainbow table).

    Also, never store the password hash anywhere but in the database. If you put it into the session or a cookie, this massively increases the risk of the hash falling into the hands of an attacker. Thereís also no reason to do that in the first place.


    What you should not do:
    PHP Code:
    // don't use this

    // creating password hash (to store it in the database)
    $password_hash md5($_POST['password']);    // bad idea! MD5 is a weak hashing algorithm, that will not withstand brute force attacks

    // checking password (for a user login)
    if (md5($_POST['password']) == $stored_password_hash) {
        
    // password is correct
    } else {
        
    // password is wrong


    What you should do:

    A secure password hashing algorithm must provide two features: Each password has to be concatenated with a unique and random salt to prevent brute force attacks against all passwords at once. And there has to be a variable ďcost factorĒ to slow down the hashing procedure and make brute force attacks more expensive.

    Donít try to implement your own algorithm, though. Use an established and well-tested library like PHPass:

    password_hash.inc.php
    PHP Code:
    // include PHPass library
    require_once dirname(__FILE__) . '/lib/phpass/PasswordHash.php';    // change this to actual location

    // create PHPass instance
    $password_hasher = new PasswordHash(10false);     // important! first argument is cost factor (10: 2**10 = 1024 iterations), second argument specifies fallback to MD5 (false: no fallback) 
    register.php
    PHP Code:
    require_once dirname(__FILE__) . '/inc/password_hash.inc.php';       // change this to actual location


    // generate password hash
    $password $_POST['password'];
    if (
    mb_strlen($password) < 6) {             // check minimum password length (to prevent insecure passwords)
        // chosen password is too short
    } elseif (mb_strlen($password) > 72) {      // check maximum password length (to prevent DoS attacks)
        // chosen password is too long
    } else {
        
    $password_hash $password_hasher->HashPassword($password);
        
    // store $password_hash in the database; use a VARCHAR(60) column, because the hash length will be at most 60 characters (depending on the internal algorithm)

    login.php
    PHP Code:
    require_once dirname(__FILE__) . '/inc/password_hash.inc.php';       // change this to actual location


    // check password
    $password $_POST['password'];
    if (
    mb_strlen($password) <= 72) {      // limit password length to 72 characters (to prevent DoS attacks)
        
    if ($password_hasher->CheckPassword($password$stored_hash)) {
            
    // password is correct
        
    } else {
            
    // password is wrong
        
    }
    } else {
        
    // password is too long

    Note that PHPass automatically generates a salt and stores it together with the actual hash. All you need to do is set the cost factor (between 4 and 31) and specify whether PHPass should use the MD5 algorithm rather than an advanced algorithm like Blowfish. A higher cost factor is more secure, but it will also generate a higher CPU load on your server. The MD5 fallback should be set to false.


    Edit March 29th 2013
    Damn, I can't edit the original posts.

    I was going to suggest the password_compat library instead of PHPass. It "emulates" the new password API that will be avaiable in PHP 5.5. So when PHP 5.5 is out, you can simply remove the library and use the native functions (unless the PHP developers mess them up again).

    Like PHPass, the library is a wrapper for the crypt() function, but it's easier to use (no classes, no objects), it has no stupid MD5 fallback, and the code is cleaner and more up to date (it uses built-in functions instead of fumbling with bits and bytes).

    But it requires PHP >= 5.3.7.
    Last edited by requinix; July 2nd, 2013 at 11:29 PM. Reason: note about password_compat
  10. #6
  11. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,959
    Rep Power
    1014
    5. Donít allow actions solely based on the login status.

    This is a somewhat less known security issue: If you only check the session cookie when validating requests, attackers can use the memberís browser to take actions on his behalf (see cross-site request forgery ).


    What you should not do:

    Many websites ďprotectĒ critical pages merely by checking the session ID on top of the script:

    blog_comment.php
    PHP Code:
    <?php

    // don't use this

    session_start();

    if (isset(
    $_SESSION['user_id'])) {      // check session
        
    if (isset($_POST['action']) && $_POST['action'] == 'comment') {
            
    // write to database                                                // bad idea! the request might have been forged
        
    }
    } else {                                
    // redirect to login page
        
    header('Location: login.php');
        exit;
    }
    ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
        <head>
            <title></title>
        </head>
        <body>
            <form action="" method="post">
                <fieldset>
                    <legend>Blog comment</legend>
                    <input type="hidden" name="action" value="comment" />
                    <textarea name="text" rows="10" cols="10"></textarea>
                    <input type="submit" />
                </fieldset>
            </form>
        </body>
    </html>
    While the user is logged in, every request will include the session cookie. And since the script only requires a valid session ID, it will accept any request coming from the userís browser during that time. So all an attacker has to do is set up a request and then trick the user or the userís browser into sending it. This can be done with a simple HTML form, which points to the target page and gets submitted automatically using JavaScript.


    What you should do:

    Cross-site request forgery can be prevented by generating a secret random token when the user has logged in. Store this token in the session and add it to every form as a hidden field. Validate form submissions by comparing the session token and the form token. Due to the same origin policy, other websites cannot read the secret token from the form. So itís pratically impossible for them to forge a valid request.

    functions.inc.php
    PHP Code:
    function generate_secure_token($length 16) {
        return 
    bin2hex(openssl_random_pseudo_bytes($length));                           // important! this has to be a crytographically secure random generator
    }

    function 
    html_escape($raw_input) {
        return 
    htmlspecialchars($raw_inputENT_QUOTES ENT_HTML401'UTF-8');

    login.php
    PHP Code:
    require_once dirname(__FILE__) . '/inc/functions.inc.php';          // change this to actual location


    // check password etc.

    $_SESSION['action_token'] = generate_secure_token(); 
    blog_comment.php
    PHP Code:
    session_start();

    if (isset($_SESSION['user_id'])) {      // check session
        if (isset($_POST['action'])) {
            if (isset($_POST['action_token']) && isset($_SESSION['action_token']) && $_POST['action_token'] == $_SESSION['action_token']) {      // check request token
                if ($_POST['action'] == 'comment') {
                    // write do database
                }
            } else {        // possible CSRF attempt
                echo 'invalid submission';
                trigger_error('possible CSRF attack', E_USER_ERROR);    // add details for logging like the user ID, the referrer (as a possible source of the attack) etc.
                exit;
            }
        }
    } else {                                // redirect to login page
        header('Location: login.php');
        exit;
    }
    ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
        <head>
            <title></title>
        </head>
        <body>
            <form action="" method="post">
                <fieldset>
                    <legend>Blog comment</legend>
                    <input type="hidden" name="action" value="comment" />
                    <input type="hidden" name="action_token" value="<?php echo html_escape($_SESSION['action_token']) ?>" />
                    <textarea name="text" rows="10" cols="10"></textarea>
                    <input type="submit" />
                </fieldset>
            </form>
        </body>
    </html>
    Note that you could theoretically increase security by generating the token per request or even per form rather than per session. However, this can easily lead to expired tokens when your members use the ďbackĒ button or open several tabs or windows of the same page. In this case you either have to ask the user to resubmit the form (which is annoying for your members), or you have to synchronize the tokens (which is difficult to implement). So the above solution should be a good compromise between security and usability.

    Be aware that the CSRF protection will be defeated if your website is vulnerable to cross-site scripting. On your own site, it is in fact possible to read the token using JavaScript.
  12. #7
  13. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,959
    Rep Power
    1014
    6. Donít use weak random numbers for critical procedures.

    Many actions like confirming a registration or resetting a password rely on random numbers. If those numbers arenít truly random, attackers might be able to guess them.


    What you should not do:

    ďRandomĒ numbers are often generated with functions like microtime, getmypid, rand, mt_rand etc.:

    forgot_password.php
    PHP Code:
    // don't use this

    $reset_key mt_rand();    // bad idea! this number is predictable
    // send $reset_key via mail 
    Since those functions all rely on known or easy-to-guess factors (the current time or the process ID), the result is predictable to a certain extend. This can be used to, for example, request a password reset for another user and then try to guess the secret token in order to change the password and capture the userís account.


    What you should do:

    Use a cryptographically secure random generator like openssl_random_pseudo_bytes to generate secret tokens. If the OpenSSL extension isnít available to you, try to read from /dev/urandom.

    functions.inc.php
    PHP Code:
    function generate_secure_token($length 16) {
        return 
    bin2hex(openssl_random_pseudo_bytes($length));                           // important! this has to be a crytographically secure random generator

    forgot_password.php
    PHP Code:
    require_once dirname(__FILE__) . '/inc/functions.inc.php';  // change this to actual location


    $reset_key generate_secure_token();
    // send $reset_key via mail 
  14. #8
  15. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,959
    Rep Power
    1014
    A small addition, because even professional software doesn't always get that right:

    Don't allow your members to simply change the email address of their account. If you do, this can be used by attackers to capture the whole account. Because all they need to do is type in their own email address, request a password request and then change the password, circumventing the "enter your old password" protection. The original user will be locked out of the account completely.

    So the email address must be as well protected as the password. Simply require the user to repeat the current password in order to change any of those two fields (that's how it's done here).

    Actually, the email address is even more important than the password (with regard to a particular website!), because it's the last resort to regain control of the account. So it would theoretically make sense to either not allow an address change at all or send a confirmation link to the old address. However, this will lead to problems if the user no longer has access to the original email account.

    So the above solution should be a good compromise. Full access to an account is possible by either having access to the email address or by knowing the password (or by guessing the password reset token).
  16. #9
  17. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Location
    India
    Posts
    2
    Rep Power
    0
    I am not aware of this stuff.
    Sound like good.
  18. #10
  19. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    1
    Rep Power
    0
    I'm surprised this actually needs to be said, as most of the developers I've encountered are well aware of these security holes. Although, I must say, I learned this the hard way when I first started PHP programming, as I was caught unaware by a spam bot filling up a blog's comments with junk. This was a number of years ago, so I don't recall the solution any more, but it was along the lines of some of the above.
  20. #11
  21. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,959
    Rep Power
    1014
    Originally Posted by AlexGabriel
    I'm surprised this actually needs to be said, as most of the developers I've encountered are well aware of these security holes.
    Well, this is mainly for amateur programmers, who often suffer from terrible online tutorials and might never have heard from things like SQL injections. When you look at code in this forum, proper escaping is almost a rarity. Some scripts have so many security holes that you just hope they're not online yet.

    Actually, judging from current software, even professional developers aren't always aware of all threats. Sure, most people understand that "... WHERE id = $_GET[id]" isn't a good idea. But you still see MD5 hashes, bad "random" numbers, CSRF vulnerabilites, encoding issues etc.
  22. #12
  23. Plays with fire
    Devshed Novice (500 - 999 posts)

    Join Date
    Aug 2003
    Location
    Barsoom
    Posts
    942
    Rep Power
    97
    I'm actually not a fan of passwords anyway. The so-called "strong" password can still be compromised with a brute force attack from rented cloud computers.

    I require passphrases instead. A jumble of 10 characters is way easier to crack and harder to remember than 4 or 5 words.
    ďBe ashamed to die until you have won some victory for humanity.Ē -- Horace Mann

    "...all men are created equal." -- US Declaration of Independence
  24. #13
  25. CSS & JS/DOM Adept
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jul 2004
    Location
    USA (verifiably)
    Posts
    20,127
    Rep Power
    4304
    Thanks for this excellent resource, Jacques1.

    Originally Posted by Frank Grimes
    I require passphrases instead. A jumble of 10 characters is way easier to crack and harder to remember than 4 or 5 words.
    Is it? If an attacker knows that words in the dictionary are most likely used, couldn't he just test groups of words instead of groups of characters? I suppose it does increase the number of possibilities by a large factor though.

    Out of curiosity, how many of the passwords you use are randomly generated? I'd say less than 1% of mine are.

    One thing that really bugs me is sites that cap the length of passwords at 12 or fewer characters. Maybe those same sites are storing raw passwords...

    Comments on this post

    • Jacques1 agrees
    Spreading knowledge, one newbie at a time.

    Check out my blog. | Learn CSS. | PHP includes | X/HTML Validator | CSS validator | Common CSS Mistakes | Common JS Mistakes

    Remember people spend most of their time on other people's sites (so don't violate web design conventions).
  26. #14
  27. Plays with fire
    Devshed Novice (500 - 999 posts)

    Join Date
    Aug 2003
    Location
    Barsoom
    Posts
    942
    Rep Power
    97
    I believe passphrases are more secure simply because of their length. If a phrase has 40 characters it would take forever to bust with a brute force attack.

    You're right, of course, with the common words, but I'd hope no one would be dumb enough to just string common words together. People should use phrases they know well and have more meaning, like movie quotes or lyrics or something.
    Last edited by Frank Grimes; February 5th, 2013 at 03:04 PM.
    ďBe ashamed to die until you have won some victory for humanity.Ē -- Horace Mann

    "...all men are created equal." -- US Declaration of Independence
  28. #15
  29. Transforming Moderator
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    14,112
    Rep Power
    9398
    The disadvantage to passphrases is that you've greatly shortened the length of the password: it's not 40 characters long, it's 4 words long. The advantage to passphrases is the size of the language: it's not 255 characters (if ASCII), it's 100K+ (if English, and the number varies).

    And the attack is still the same whether the password is a set of characters or a set of words: I try every permutation of symbols (characters/words) from the input language (on the keyboard/in the dictionary) until I get a match. The difference is that the search space for a character-based password is considerably smaller than that of a word-based passphrase.

    The analogies continue, such as
    * Using common pairs of words ("I love" X) is like common pairs of characters ("qu")
    * Substituting numbers for letters (cat->c4t) is like hitting shift for a letter (a->A)
Page 1 of 3 123 Last
  • Jump to page:

IMN logo majestic logo threadwatch logo seochat tools logo