While I see nothing in that script that's actually hackable, there are a few things that could be improved upon.
Firstly, I'd highly recommend that you check that both $POST['username'] and $POST['password'] have values. Otherwise the script will throw annoying undefined errors when someone doesn't fill a field in.
if (isset($_POST['submit']) && !empty($_POST['username']) && !empty($_POST['password']))
Also, I've found from my own experiences, and from reading around on the net, you should call session_start() first if you intend to use it in your script.
With your SQL string, there seems to be no reason for you to be retrieving every database column in that row if you're only using the username column. This isn't a serious problem, it just uses more resources than needed here.
Finally, I'm fairly sure that your redirect will not work as expected. If you output any kind of text before a redirect, it will give you a "headers already sent" error.
Here's your cleaned up script. I didn't touch that bit of HTML at the bottom, cause I didn't have enough time. 🙂
<?php
session_start();
if (isset($_POST['submit']) && !empty($_POST['username']) && !empty($_POST['password']))
{
mysql_connect("localhost", "root", "pass");
mysql_select_db("shadowcms");
$username = $_POST['username'];
$password = $_POST['password'];
$username = mysql_real_escape_string($username);
$password = md5($password);
$sql = mysql_query('SELECT username FROM users WHERE username = "'. $username. '" AND password = "'. $password. '"');
$nr = mysql_num_rows($sql);
if ($nr == 0)
{
echo'
<div class="errormsg" style="text-align: center;">
<p>Username or password is incorrect.</p>
</div>';
}
else
{
while ($row = mysql_fetch_array($sql))
{
$_SESSION['lia'] = $row['username'];
}
echo'
Welcome, '. $_SESSION['lia']. '!';
}
}
?>