PHP password-resetting page












2












$begingroup$


I am producing a PHP code and I want to implement it in my server to do its function. My question is, are there any vulnerabilities that I should correct?



I tried to establish the session first then I will initiate a SQL connection and I will ask the user to enter his email. Also I added the reset function of his email.



<?php
if ($_SESSION['admin'] !== true) {
header('Location: /login.php?');
}

$conn = new mysqli("localhost","admin","password","db");

if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}

$msg = '';
if (isset($_POST['submit'])) {
$email = $_POST['email'];
$sql = "SELECT * FROM users WHERE email = $email;";
$result = @$conn->query($sql);
if ($result->num_rows == 0) {
die("This email: $email is incorrect");
}
$row = $result->fetch_assoc();
$id = $row["id"];
$surename = $row["surename"];

$sql = "SELECT * from users JOIN password_resets ON (password_resets.user_id=users.id) WHERE id=$id;";
$result = @$conn->query($query);
if ($result->num_rows == 0) {
$insert_sql = "INSERT INTO password_resets (user_id, reset_timestamp) VALUES ($id, unix_timestamp());";
if ($conn->query($insert_sql) !== TRUE) {
die("Error: " . $insert_sql . "<br>" . $conn->error);
}
}
$result = $conn->query($query);
$row = $result->fetch_assoc();

$link = "https://".$_SERVER['SERVER_NAME']."/reset.php?id=".$row['id'] ."&timestamp=".$row['reset_timestamp'];
$message = "Hi, $surename,

Here's your password reset link: $link";
$headers = "From: ".$_SESSION['first_name']." ".$_SESSION['last_name']." <".$_SESSION['email'].">";
mail($email,"Your password reset link",$message,$headers);
$msg = "Password reset for $email sent!";
?>
<html>
<head><title>Reset password for a user</title></head>
<body>
<form>
<div class="message"><?=$msg ?></div>
<input type="text" width=80 name="email">
<input type="submit" name="submit" value="Send">
</form>
</body>
</html>
<?php
}









share|improve this question









New contributor




helloworld is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$








  • 1




    $begingroup$
    The current question title, which states your concerns about the code, is too general to be useful here. The site standard is for the title to simply state the task accomplished by the code. Please see How to Ask for examples, and revise the title accordingly.
    $endgroup$
    – Jamal
    5 hours ago
















2












$begingroup$


I am producing a PHP code and I want to implement it in my server to do its function. My question is, are there any vulnerabilities that I should correct?



I tried to establish the session first then I will initiate a SQL connection and I will ask the user to enter his email. Also I added the reset function of his email.



<?php
if ($_SESSION['admin'] !== true) {
header('Location: /login.php?');
}

$conn = new mysqli("localhost","admin","password","db");

if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}

$msg = '';
if (isset($_POST['submit'])) {
$email = $_POST['email'];
$sql = "SELECT * FROM users WHERE email = $email;";
$result = @$conn->query($sql);
if ($result->num_rows == 0) {
die("This email: $email is incorrect");
}
$row = $result->fetch_assoc();
$id = $row["id"];
$surename = $row["surename"];

$sql = "SELECT * from users JOIN password_resets ON (password_resets.user_id=users.id) WHERE id=$id;";
$result = @$conn->query($query);
if ($result->num_rows == 0) {
$insert_sql = "INSERT INTO password_resets (user_id, reset_timestamp) VALUES ($id, unix_timestamp());";
if ($conn->query($insert_sql) !== TRUE) {
die("Error: " . $insert_sql . "<br>" . $conn->error);
}
}
$result = $conn->query($query);
$row = $result->fetch_assoc();

$link = "https://".$_SERVER['SERVER_NAME']."/reset.php?id=".$row['id'] ."&timestamp=".$row['reset_timestamp'];
$message = "Hi, $surename,

Here's your password reset link: $link";
$headers = "From: ".$_SESSION['first_name']." ".$_SESSION['last_name']." <".$_SESSION['email'].">";
mail($email,"Your password reset link",$message,$headers);
$msg = "Password reset for $email sent!";
?>
<html>
<head><title>Reset password for a user</title></head>
<body>
<form>
<div class="message"><?=$msg ?></div>
<input type="text" width=80 name="email">
<input type="submit" name="submit" value="Send">
</form>
</body>
</html>
<?php
}









share|improve this question









New contributor




helloworld is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$








  • 1




    $begingroup$
    The current question title, which states your concerns about the code, is too general to be useful here. The site standard is for the title to simply state the task accomplished by the code. Please see How to Ask for examples, and revise the title accordingly.
    $endgroup$
    – Jamal
    5 hours ago














2












2








2





$begingroup$


I am producing a PHP code and I want to implement it in my server to do its function. My question is, are there any vulnerabilities that I should correct?



I tried to establish the session first then I will initiate a SQL connection and I will ask the user to enter his email. Also I added the reset function of his email.



<?php
if ($_SESSION['admin'] !== true) {
header('Location: /login.php?');
}

$conn = new mysqli("localhost","admin","password","db");

if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}

$msg = '';
if (isset($_POST['submit'])) {
$email = $_POST['email'];
$sql = "SELECT * FROM users WHERE email = $email;";
$result = @$conn->query($sql);
if ($result->num_rows == 0) {
die("This email: $email is incorrect");
}
$row = $result->fetch_assoc();
$id = $row["id"];
$surename = $row["surename"];

$sql = "SELECT * from users JOIN password_resets ON (password_resets.user_id=users.id) WHERE id=$id;";
$result = @$conn->query($query);
if ($result->num_rows == 0) {
$insert_sql = "INSERT INTO password_resets (user_id, reset_timestamp) VALUES ($id, unix_timestamp());";
if ($conn->query($insert_sql) !== TRUE) {
die("Error: " . $insert_sql . "<br>" . $conn->error);
}
}
$result = $conn->query($query);
$row = $result->fetch_assoc();

$link = "https://".$_SERVER['SERVER_NAME']."/reset.php?id=".$row['id'] ."&timestamp=".$row['reset_timestamp'];
$message = "Hi, $surename,

Here's your password reset link: $link";
$headers = "From: ".$_SESSION['first_name']." ".$_SESSION['last_name']." <".$_SESSION['email'].">";
mail($email,"Your password reset link",$message,$headers);
$msg = "Password reset for $email sent!";
?>
<html>
<head><title>Reset password for a user</title></head>
<body>
<form>
<div class="message"><?=$msg ?></div>
<input type="text" width=80 name="email">
<input type="submit" name="submit" value="Send">
</form>
</body>
</html>
<?php
}









share|improve this question









New contributor




helloworld is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$




I am producing a PHP code and I want to implement it in my server to do its function. My question is, are there any vulnerabilities that I should correct?



I tried to establish the session first then I will initiate a SQL connection and I will ask the user to enter his email. Also I added the reset function of his email.



<?php
if ($_SESSION['admin'] !== true) {
header('Location: /login.php?');
}

$conn = new mysqli("localhost","admin","password","db");

if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}

$msg = '';
if (isset($_POST['submit'])) {
$email = $_POST['email'];
$sql = "SELECT * FROM users WHERE email = $email;";
$result = @$conn->query($sql);
if ($result->num_rows == 0) {
die("This email: $email is incorrect");
}
$row = $result->fetch_assoc();
$id = $row["id"];
$surename = $row["surename"];

$sql = "SELECT * from users JOIN password_resets ON (password_resets.user_id=users.id) WHERE id=$id;";
$result = @$conn->query($query);
if ($result->num_rows == 0) {
$insert_sql = "INSERT INTO password_resets (user_id, reset_timestamp) VALUES ($id, unix_timestamp());";
if ($conn->query($insert_sql) !== TRUE) {
die("Error: " . $insert_sql . "<br>" . $conn->error);
}
}
$result = $conn->query($query);
$row = $result->fetch_assoc();

$link = "https://".$_SERVER['SERVER_NAME']."/reset.php?id=".$row['id'] ."&timestamp=".$row['reset_timestamp'];
$message = "Hi, $surename,

Here's your password reset link: $link";
$headers = "From: ".$_SESSION['first_name']." ".$_SESSION['last_name']." <".$_SESSION['email'].">";
mail($email,"Your password reset link",$message,$headers);
$msg = "Password reset for $email sent!";
?>
<html>
<head><title>Reset password for a user</title></head>
<body>
<form>
<div class="message"><?=$msg ?></div>
<input type="text" width=80 name="email">
<input type="submit" name="submit" value="Send">
</form>
</body>
</html>
<?php
}






php security authentication email mysqli






share|improve this question









New contributor




helloworld is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




helloworld is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 11 mins ago









200_success

129k15153415




129k15153415






New contributor




helloworld is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 7 hours ago









helloworldhelloworld

141




141




New contributor




helloworld is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





helloworld is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






helloworld is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








  • 1




    $begingroup$
    The current question title, which states your concerns about the code, is too general to be useful here. The site standard is for the title to simply state the task accomplished by the code. Please see How to Ask for examples, and revise the title accordingly.
    $endgroup$
    – Jamal
    5 hours ago














  • 1




    $begingroup$
    The current question title, which states your concerns about the code, is too general to be useful here. The site standard is for the title to simply state the task accomplished by the code. Please see How to Ask for examples, and revise the title accordingly.
    $endgroup$
    – Jamal
    5 hours ago








1




1




$begingroup$
The current question title, which states your concerns about the code, is too general to be useful here. The site standard is for the title to simply state the task accomplished by the code. Please see How to Ask for examples, and revise the title accordingly.
$endgroup$
– Jamal
5 hours ago




$begingroup$
The current question title, which states your concerns about the code, is too general to be useful here. The site standard is for the title to simply state the task accomplished by the code. Please see How to Ask for examples, and revise the title accordingly.
$endgroup$
– Jamal
5 hours ago










1 Answer
1






active

oldest

votes


















2












$begingroup$

Your code is wide open to SQL Injection which is the most dangerous web vulnerability. This occurs when you execute SQL queries with unsanitized user data. By placing the raw $_POST variable directly in your query you are allowing an attacker to inject their own SQL into your query and execute it. They can do anything from stealing data to deleting your database.



To combat this you must use parameterized queries. Stack Overflow covers this very well but here's what your code would like if you use mysqli with prepared statements:



$stmt = $dbConnection->prepare('SELECT * FROM users WHERE email = ?');
$stmt->bind_param('s', $email); // 's' specifies the variable type => 'string'

$stmt->execute();

$result = $stmt->get_result();
$row = $result->fetch_assoc();


You also are wide open to Cross-site scripting (XSS) attacks which is the #7 web vulnerability. This occurs because you take raw $_POST data and output it directly into your HTML. An attacker can place malicious code in this value and attack your users and site once it is rendered by the browser.



When outputting user data, always escape that data. Stack Overflow covers this as well. In PHP you can do this by using htmlspecialchars().



<?= htmlspecialchars($msg, ENT_QUOTES, 'UTF-8'); ?>


You will notice that the one $_POST variable, $_POST['email'], has left your site wide open to attack. Before you even attempt to use it you should validate it indeed is a valid email address. If it is not, you should report an error and not attempt to use it as it obviously is invalid and useless anyway.



PHP offers an easy way to validate an email addresses. filter_var() with the FILTER_VALIDATE_EMAIL flag will validate if an email address is valid.



$email = $_POST['email'];
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
// email is invalid. report error and abort.
}


On a different note, you start your script off by checking to see if a user is an admin. If they are not you use header() to do a redirect away from that page. That's usually okay but you should follow it with a call to exit() to ensure the script stops executing. If not, the code below may still execute and, combined with other vulnerabilities in the page, leave you open to attack.



if ($_SESSION['admin'] !== true) {
header('Location: /login.php?');
exit;
}





share|improve this answer











$endgroup$













    Your Answer





    StackExchange.ifUsing("editor", function () {
    return StackExchange.using("mathjaxEditing", function () {
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
    });
    });
    }, "mathjax-editing");

    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "196"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });






    helloworld is a new contributor. Be nice, and check out our Code of Conduct.










    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f213549%2fphp-password-resetting-page%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    2












    $begingroup$

    Your code is wide open to SQL Injection which is the most dangerous web vulnerability. This occurs when you execute SQL queries with unsanitized user data. By placing the raw $_POST variable directly in your query you are allowing an attacker to inject their own SQL into your query and execute it. They can do anything from stealing data to deleting your database.



    To combat this you must use parameterized queries. Stack Overflow covers this very well but here's what your code would like if you use mysqli with prepared statements:



    $stmt = $dbConnection->prepare('SELECT * FROM users WHERE email = ?');
    $stmt->bind_param('s', $email); // 's' specifies the variable type => 'string'

    $stmt->execute();

    $result = $stmt->get_result();
    $row = $result->fetch_assoc();


    You also are wide open to Cross-site scripting (XSS) attacks which is the #7 web vulnerability. This occurs because you take raw $_POST data and output it directly into your HTML. An attacker can place malicious code in this value and attack your users and site once it is rendered by the browser.



    When outputting user data, always escape that data. Stack Overflow covers this as well. In PHP you can do this by using htmlspecialchars().



    <?= htmlspecialchars($msg, ENT_QUOTES, 'UTF-8'); ?>


    You will notice that the one $_POST variable, $_POST['email'], has left your site wide open to attack. Before you even attempt to use it you should validate it indeed is a valid email address. If it is not, you should report an error and not attempt to use it as it obviously is invalid and useless anyway.



    PHP offers an easy way to validate an email addresses. filter_var() with the FILTER_VALIDATE_EMAIL flag will validate if an email address is valid.



    $email = $_POST['email'];
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    // email is invalid. report error and abort.
    }


    On a different note, you start your script off by checking to see if a user is an admin. If they are not you use header() to do a redirect away from that page. That's usually okay but you should follow it with a call to exit() to ensure the script stops executing. If not, the code below may still execute and, combined with other vulnerabilities in the page, leave you open to attack.



    if ($_SESSION['admin'] !== true) {
    header('Location: /login.php?');
    exit;
    }





    share|improve this answer











    $endgroup$


















      2












      $begingroup$

      Your code is wide open to SQL Injection which is the most dangerous web vulnerability. This occurs when you execute SQL queries with unsanitized user data. By placing the raw $_POST variable directly in your query you are allowing an attacker to inject their own SQL into your query and execute it. They can do anything from stealing data to deleting your database.



      To combat this you must use parameterized queries. Stack Overflow covers this very well but here's what your code would like if you use mysqli with prepared statements:



      $stmt = $dbConnection->prepare('SELECT * FROM users WHERE email = ?');
      $stmt->bind_param('s', $email); // 's' specifies the variable type => 'string'

      $stmt->execute();

      $result = $stmt->get_result();
      $row = $result->fetch_assoc();


      You also are wide open to Cross-site scripting (XSS) attacks which is the #7 web vulnerability. This occurs because you take raw $_POST data and output it directly into your HTML. An attacker can place malicious code in this value and attack your users and site once it is rendered by the browser.



      When outputting user data, always escape that data. Stack Overflow covers this as well. In PHP you can do this by using htmlspecialchars().



      <?= htmlspecialchars($msg, ENT_QUOTES, 'UTF-8'); ?>


      You will notice that the one $_POST variable, $_POST['email'], has left your site wide open to attack. Before you even attempt to use it you should validate it indeed is a valid email address. If it is not, you should report an error and not attempt to use it as it obviously is invalid and useless anyway.



      PHP offers an easy way to validate an email addresses. filter_var() with the FILTER_VALIDATE_EMAIL flag will validate if an email address is valid.



      $email = $_POST['email'];
      if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
      // email is invalid. report error and abort.
      }


      On a different note, you start your script off by checking to see if a user is an admin. If they are not you use header() to do a redirect away from that page. That's usually okay but you should follow it with a call to exit() to ensure the script stops executing. If not, the code below may still execute and, combined with other vulnerabilities in the page, leave you open to attack.



      if ($_SESSION['admin'] !== true) {
      header('Location: /login.php?');
      exit;
      }





      share|improve this answer











      $endgroup$
















        2












        2








        2





        $begingroup$

        Your code is wide open to SQL Injection which is the most dangerous web vulnerability. This occurs when you execute SQL queries with unsanitized user data. By placing the raw $_POST variable directly in your query you are allowing an attacker to inject their own SQL into your query and execute it. They can do anything from stealing data to deleting your database.



        To combat this you must use parameterized queries. Stack Overflow covers this very well but here's what your code would like if you use mysqli with prepared statements:



        $stmt = $dbConnection->prepare('SELECT * FROM users WHERE email = ?');
        $stmt->bind_param('s', $email); // 's' specifies the variable type => 'string'

        $stmt->execute();

        $result = $stmt->get_result();
        $row = $result->fetch_assoc();


        You also are wide open to Cross-site scripting (XSS) attacks which is the #7 web vulnerability. This occurs because you take raw $_POST data and output it directly into your HTML. An attacker can place malicious code in this value and attack your users and site once it is rendered by the browser.



        When outputting user data, always escape that data. Stack Overflow covers this as well. In PHP you can do this by using htmlspecialchars().



        <?= htmlspecialchars($msg, ENT_QUOTES, 'UTF-8'); ?>


        You will notice that the one $_POST variable, $_POST['email'], has left your site wide open to attack. Before you even attempt to use it you should validate it indeed is a valid email address. If it is not, you should report an error and not attempt to use it as it obviously is invalid and useless anyway.



        PHP offers an easy way to validate an email addresses. filter_var() with the FILTER_VALIDATE_EMAIL flag will validate if an email address is valid.



        $email = $_POST['email'];
        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        // email is invalid. report error and abort.
        }


        On a different note, you start your script off by checking to see if a user is an admin. If they are not you use header() to do a redirect away from that page. That's usually okay but you should follow it with a call to exit() to ensure the script stops executing. If not, the code below may still execute and, combined with other vulnerabilities in the page, leave you open to attack.



        if ($_SESSION['admin'] !== true) {
        header('Location: /login.php?');
        exit;
        }





        share|improve this answer











        $endgroup$



        Your code is wide open to SQL Injection which is the most dangerous web vulnerability. This occurs when you execute SQL queries with unsanitized user data. By placing the raw $_POST variable directly in your query you are allowing an attacker to inject their own SQL into your query and execute it. They can do anything from stealing data to deleting your database.



        To combat this you must use parameterized queries. Stack Overflow covers this very well but here's what your code would like if you use mysqli with prepared statements:



        $stmt = $dbConnection->prepare('SELECT * FROM users WHERE email = ?');
        $stmt->bind_param('s', $email); // 's' specifies the variable type => 'string'

        $stmt->execute();

        $result = $stmt->get_result();
        $row = $result->fetch_assoc();


        You also are wide open to Cross-site scripting (XSS) attacks which is the #7 web vulnerability. This occurs because you take raw $_POST data and output it directly into your HTML. An attacker can place malicious code in this value and attack your users and site once it is rendered by the browser.



        When outputting user data, always escape that data. Stack Overflow covers this as well. In PHP you can do this by using htmlspecialchars().



        <?= htmlspecialchars($msg, ENT_QUOTES, 'UTF-8'); ?>


        You will notice that the one $_POST variable, $_POST['email'], has left your site wide open to attack. Before you even attempt to use it you should validate it indeed is a valid email address. If it is not, you should report an error and not attempt to use it as it obviously is invalid and useless anyway.



        PHP offers an easy way to validate an email addresses. filter_var() with the FILTER_VALIDATE_EMAIL flag will validate if an email address is valid.



        $email = $_POST['email'];
        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        // email is invalid. report error and abort.
        }


        On a different note, you start your script off by checking to see if a user is an admin. If they are not you use header() to do a redirect away from that page. That's usually okay but you should follow it with a call to exit() to ensure the script stops executing. If not, the code below may still execute and, combined with other vulnerabilities in the page, leave you open to attack.



        if ($_SESSION['admin'] !== true) {
        header('Location: /login.php?');
        exit;
        }






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited 6 hours ago

























        answered 7 hours ago









        John CondeJohn Conde

        31829




        31829






















            helloworld is a new contributor. Be nice, and check out our Code of Conduct.










            draft saved

            draft discarded


















            helloworld is a new contributor. Be nice, and check out our Code of Conduct.













            helloworld is a new contributor. Be nice, and check out our Code of Conduct.












            helloworld is a new contributor. Be nice, and check out our Code of Conduct.
















            Thanks for contributing an answer to Code Review Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            Use MathJax to format equations. MathJax reference.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f213549%2fphp-password-resetting-page%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Costa Masnaga

            Fotorealismo

            Sidney Franklin