Hey guys, this morning I decided to start working on something bigger than usual. I wanted to try and make my own bulletin board software. This won't be up for release or anything but I thought some of you might want to track my journey. My design skills are questionable, but this project isn't about that. This project is to expand my knowledge of PHP and create and expand on something until, maybe, it is usable and user friendly (possibly release it then).
- Basic design
- Database user structure
- Database forum structure
- User registration
- Account activation (Via email link)
- Login/Logout
- Basic forum retrieval
- View forum threads
- Memberlist
- Git commit
Another reason I am posting this thread is to enlist the help of some white hat hackers, who would like to test the website for exploits and vulnerabilities. If you would like to do that, report anything to [email protected].
Once again, don't flame me over my website design, I'm not aiming for a picture perfect website.
Let me know what you think, I will happily accept suggestions.
Sounds interesting, are you going to post the source code online (github, etc)?
Rollback Post to RevisionRollBack
"If tyranny and oppression come to this land, it will be in the guise of fighting a foreign enemy. The loss of Liberty at home is to be charged to the provisions against danger, real or imagined, from abroad." - James Madison
Yes, I'd like to see the exact code for the login procedure, session checking, etc. I'm interested in seeing how secure it is. I can advice you in ways to make it more secure if current security measures are insufficient. At the very least, I'm glad I saw a session hash in the cookie. I'd crucify you if I saw a plain-text username or, even worse, password in there.
Yes, I'd like to see the exact code for the login procedure, session checking, etc. I'm interested in seeing how secure it is. I can advice you in ways to make it more secure if current security measures are insufficient. At the very least, I'm glad I saw a session hash in the cookie. I'd crucify you if I saw a plain-text username or, even worse, password in there.
Seeing as you guys would like to see the code, I might clean up the code a bit and put it up. My current password security consists of sha1 hashing the username + password and a salt (I've been told it is a good way to store passwords).
It is a good way to store passwords. MD5 has way, way too many rainbow tables made for it to be considered secure, even with salts. SHA1, by taking so much longer to calculate, will last a fair while longer than MD5 did.
By no means am I as experienced as MrQuizzles, but I still think that SHA1 has been shown to have some problems. If you ran it through SHA256 or SHA512 (plus a salt), that would probably be even better. If I am wrong, please do correct me.
Also, SHA3 will be selected sometime this year which will be totally different from previous versions of the SHA algorithms.
Rollback Post to RevisionRollBack
"If tyranny and oppression come to this land, it will be in the guise of fighting a foreign enemy. The loss of Liberty at home is to be charged to the provisions against danger, real or imagined, from abroad." - James Madison
By no means am I as experienced as MrQuizzles, but I still think that SHA1 has been shown to have some problems. If you ran it through SHA256 or SHA512 (plus a salt), that would probably be even better. If I am wrong, please do correct me.
If you're not salting, then you shouldn't be using SHA1. You should always salt, though. To get a sense of how many hashes have been calculated for SHA1 vs MD5, go here. You'll find that there's barely 200GB of SHA1 hashes vs the 2TB of MD5 hashes that exist. SHA1 is still plenty secure and will remain so for a good, long while.
That said, if you can afford the space and computational costs of SHA512, go for it. Do realize that, on a high-use system, running a lot of those hashes can actually be very expensive in terms of CPU time.
Update: added extra extra session checking. It now checks to see if the logged in user matches the session hash.
What do you mean by that? The session hash should be what you're using to determine which user is even logged in in the first place. Checking the username against the hash seems circular to me.
When a session hash is generated, it usually gets put in 2 places:
1. In a cookie held by the user
2. In a database held by the site
The hash is then connected to that user, so you can check the database and say "this hash belongs to this user", which allows you to make the assumption "I'm being presented with this hash, it therefore must come from this user." Session-jacking is possible, so we must strive to make it unlikely as possible by making the hash unpredictable and, if you really wanna go all in, using SSL encryption (so even if the packets are sniffed, the hash cannot be determined).
What do you mean by that? The session hash should be what you're using to determine which user is even logged in in the first place. Checking the username against the hash seems circular to me.
When a session hash is generated, it usually gets put in 2 places:
1. In a cookie held by the user
2. In a database held by the site
The hash is then connected to that user, so you can check the database and say "this hash belongs to this user", which allows you to make the assumption "I'm being presented with this hash, it therefore must come from this user." Session-jacking is possible, so we must strive to make it unlikely as possible by making the hash unpredictable and, if you really wanna go all in, using SSL encryption (so even if the packets are sniffed, the hash cannot be determined).
I thought a new session hash was generated everytime the user comes back to the webpage? What I am doing currently is comparing the user hash generated when the account is created with the username. If both exist at the same time then they are logged in. Maybe take a look at the code now that I have committed it: https://github.com/logicx/CustomBB
I've probably done a few things wrong but yea, all in the learning experience
I thought a new session hash was generated everytime the user comes back to the webpage? What I am doing currently is comparing the user hash generated when the account is created with the username. If both exist at the same time then they are logged in. Maybe take a look at the code now that I have committed it: https://github.com/logicx/CustomBB
I've probably done a few things wrong but yea, all in the learning experience
Well yes, the hash is reassigned every time a person visits the site. That makes it more difficult to session-jack, and that's a good thing. The point of a session hash is to be a unique and difficult-to-predict identifier for any logged-in user. Being stored in a cookie, it's sent over to you in the request. It's your way of telling who is who.
PHP Sessions store data on the server and give the user a unique session hash. Whenever that session hash is presented to the server, it brings forth that data to be used in the $_SESSION array. Only the hash ever goes out to the client, everything else stays on the server. All you need to do is tie the hash to a userId (shove the userId into the session data), and you can securely check which user corresponds to the hash that you have just been sent.
Making a further check against a static variable does not provide very much security. Security comes best through values that are constantly changing. If you really want a higher degree of security, then you're going to want to use cryptographic nonces (like with the user activation link). This could be considered going a bit overboard for just forum software.
Oh, also, get your controllers out of your views and then get your models out of your controllers. SQL queries and HTML should NEVER appear in the same component. Look at this to get a sense of what you shoot be shooting for.
Well yes, the hash is reassigned every time a person visits the site. That makes it more difficult to session-jack, and that's a good thing. The point of a session hash is to be a unique and difficult-to-predict identifier for any logged-in user. Being stored in a cookie, it's sent over to you in the request. It's your way of telling who is who.
PHP Sessions store data on the server and give the user a unique session hash. Whenever that session hash is presented to the server, it brings forth that data to be used in the $_SESSION array. Only the hash ever goes out to the client, everything else stays on the server. All you need to do is tie the hash to a userId (shove the userId into the session data), and you can securely check which user corresponds to the hash that you have just been sent.
Making a further check against a static variable does not provide very much security. Security comes best through values that are constantly changing. If you really want a higher degree of security, then you're going to want to use cryptographic nonces (like with the user activation link). This could be considered going a bit overboard for just forum software.
Oh, also, get your controllers out of your views and then get your models out of your controllers. SQL queries and HTML should NEVER appear in the same component. Look at this to get a sense of what you shoot be shooting for.
Thanks. I'm a little confused about the last statement though. Do you mean I should put all my queries into a seperate file to act as predefined statements?
EDIT: I looked it up and read over it. I think I did manage to accomplish MVC sort of.. For example I now load the memberlist like so:
You should use PDO to reduce your chance of SQL injection. Instead of just dumping your form submitted variables directly into a static SQL string w/o any checks, you can add them as "variables" after the string is built.
So like this line:
$query = mysql_query("INSERT INTO users(`username`, `password`, `email`,`regip`,`conf`,`hash`,`dor`)
VALUES('$username', '$new_pass', '$email','$regip',$conf, '$hash','$today')") or die(mysql_error());
Thanks. I'm a little confused about the last statement though. Do you mean I should put all my queries into a seperate file to act as predefined statements?
EDIT: I looked it up and read over it. I think I did manage to accomplish MVC sort of.. For example I now load the memberlist like so:
$db = new users();
print($db->getUsers());
Would that be correct?
You should create models for the data you're going to be working with and then organize them into modules by creating helper classes (such as mappers, validators, etc.) for them. Similarly, you should create managers for any resources you're going to be working with. This way, you can keep your domain logic separate from your controller logic, which is then separate from your view logic. It's such a big topic that it's difficult to explain. I'm actually currently writing about it for my next post on the principles of software design: Modularity.
In short, what I'm saying is that you need to refactor your solution into distinct layers or else you will have fallen prey to the evil that is temporal coupling - The act of putting code snippets in the same place merely because they will be executed at the same time. Temporal coupling needs to be avoided because it, more than anything else, is responsible for so many bloated and incomprehensible files. Things may seem manageable now, but as you develop the program further, each page will require more and more logic to be put into it. That is when things will become messy.
When creating each component, keep to a strict separation of concerns. Your views should only be responsible for displaying content. They shouldn't be deciding which content to retrieve (that's the controller's job), they shouldn't be calling databases to get that content (that's part of the model's duties; an external resource interfacer), they shouldn't be implementing rules that preserve data integrity (this is an example of domain logic; that's the duty of a resource manager).
The goal is to create layers of insulation around your program. If done successfully, then your program will be resistant to changes made to the outside environment since the core of the program will not be dependent upon it, just a mapper or interfacer class.
The name of MVC is a bit misleading in that more than 3 layers are actually required. In all, your program should consist of these layers that connect to each other in this order:
Presentation - receives data from the controller and displays it
Controller - decides which domain logic to run in order to retrieve and/or manipulate data
Domain Logic - enforces domain logic attached to retrieving and manipulating the data
Mapping Logic - Transforms raw data from the resource interfacer into the data models
Resource Interfacing - actually calls resources to get or put data; does not implement domain logic
Data - the actual data that we'll be working with; a database or webservice
And finally there's the models themselves, which aren't really a layer. Think of them like datagrams that get passed around throughout the program.
And then each layer should consist of multiple classes that are each concerned about a specific data element, such as a post, a board, or a user. Each collection of layers that is concerned with a single data element or set of related data elements constitutes a module. Keeping to this setup will ensure a robust and resilient implementation that's easy to manage and make changes to.
Link to website: http://custombb.no-ip.org/
GitHub project page: https://github.com/logicx/CustomBB
Pictures:
Things finished so far:
- Basic design
- Database user structure
- Database forum structure
- User registration
- Account activation (Via email link)
- Login/Logout
- Basic forum retrieval
- View forum threads
- Memberlist
- Git commit
Another reason I am posting this thread is to enlist the help of some white hat hackers, who would like to test the website for exploits and vulnerabilities. If you would like to do that, report anything to [email protected].
Once again, don't flame me over my website design, I'm not aiming for a picture perfect website.
Let me know what you think, I will happily accept suggestions.
Regards, Logicx.
Want a place to advertise your Minecraft server? try MyMCStatus.net now!
Possibly, will see how it goes first.
Want a place to advertise your Minecraft server? try MyMCStatus.net now!
Seeing as you guys would like to see the code, I might clean up the code a bit and put it up. My current password security consists of sha1 hashing the username + password and a salt (I've been told it is a good way to store passwords).
Want a place to advertise your Minecraft server? try MyMCStatus.net now!
Something I could never get into.
Good luck with your project, seems like it might be interesting to watch you build it.
Want a place to advertise your Minecraft server? try MyMCStatus.net now!
Also, SHA3 will be selected sometime this year which will be totally different from previous versions of the SHA algorithms.
If you're not salting, then you shouldn't be using SHA1. You should always salt, though. To get a sense of how many hashes have been calculated for SHA1 vs MD5, go here. You'll find that there's barely 200GB of SHA1 hashes vs the 2TB of MD5 hashes that exist. SHA1 is still plenty secure and will remain so for a good, long while.
That said, if you can afford the space and computational costs of SHA512, go for it. Do realize that, on a high-use system, running a lot of those hashes can actually be very expensive in terms of CPU time.
Want a place to advertise your Minecraft server? try MyMCStatus.net now!
What do you mean by that? The session hash should be what you're using to determine which user is even logged in in the first place. Checking the username against the hash seems circular to me.
When a session hash is generated, it usually gets put in 2 places:
1. In a cookie held by the user
2. In a database held by the site
The hash is then connected to that user, so you can check the database and say "this hash belongs to this user", which allows you to make the assumption "I'm being presented with this hash, it therefore must come from this user." Session-jacking is possible, so we must strive to make it unlikely as possible by making the hash unpredictable and, if you really wanna go all in, using SSL encryption (so even if the packets are sniffed, the hash cannot be determined).
I thought a new session hash was generated everytime the user comes back to the webpage? What I am doing currently is comparing the user hash generated when the account is created with the username. If both exist at the same time then they are logged in. Maybe take a look at the code now that I have committed it: https://github.com/logicx/CustomBB
I've probably done a few things wrong but yea, all in the learning experience
Want a place to advertise your Minecraft server? try MyMCStatus.net now!
Well yes, the hash is reassigned every time a person visits the site. That makes it more difficult to session-jack, and that's a good thing. The point of a session hash is to be a unique and difficult-to-predict identifier for any logged-in user. Being stored in a cookie, it's sent over to you in the request. It's your way of telling who is who.
PHP Sessions store data on the server and give the user a unique session hash. Whenever that session hash is presented to the server, it brings forth that data to be used in the $_SESSION array. Only the hash ever goes out to the client, everything else stays on the server. All you need to do is tie the hash to a userId (shove the userId into the session data), and you can securely check which user corresponds to the hash that you have just been sent.
Making a further check against a static variable does not provide very much security. Security comes best through values that are constantly changing. If you really want a higher degree of security, then you're going to want to use cryptographic nonces (like with the user activation link). This could be considered going a bit overboard for just forum software.
Oh, also, get your controllers out of your views and then get your models out of your controllers. SQL queries and HTML should NEVER appear in the same component. Look at this to get a sense of what you shoot be shooting for.
Thanks. I'm a little confused about the last statement though. Do you mean I should put all my queries into a seperate file to act as predefined statements?
EDIT: I looked it up and read over it. I think I did manage to accomplish MVC sort of.. For example I now load the memberlist like so:
Would that be correct?
Want a place to advertise your Minecraft server? try MyMCStatus.net now!
So like this line:
Would be:
As an added bonus you don't have to worry with doing any embedded quote checking.
You should create models for the data you're going to be working with and then organize them into modules by creating helper classes (such as mappers, validators, etc.) for them. Similarly, you should create managers for any resources you're going to be working with. This way, you can keep your domain logic separate from your controller logic, which is then separate from your view logic. It's such a big topic that it's difficult to explain. I'm actually currently writing about it for my next post on the principles of software design: Modularity.
In short, what I'm saying is that you need to refactor your solution into distinct layers or else you will have fallen prey to the evil that is temporal coupling - The act of putting code snippets in the same place merely because they will be executed at the same time. Temporal coupling needs to be avoided because it, more than anything else, is responsible for so many bloated and incomprehensible files. Things may seem manageable now, but as you develop the program further, each page will require more and more logic to be put into it. That is when things will become messy.
When creating each component, keep to a strict separation of concerns. Your views should only be responsible for displaying content. They shouldn't be deciding which content to retrieve (that's the controller's job), they shouldn't be calling databases to get that content (that's part of the model's duties; an external resource interfacer), they shouldn't be implementing rules that preserve data integrity (this is an example of domain logic; that's the duty of a resource manager).
The goal is to create layers of insulation around your program. If done successfully, then your program will be resistant to changes made to the outside environment since the core of the program will not be dependent upon it, just a mapper or interfacer class.
The name of MVC is a bit misleading in that more than 3 layers are actually required. In all, your program should consist of these layers that connect to each other in this order:
Presentation - receives data from the controller and displays it
Controller - decides which domain logic to run in order to retrieve and/or manipulate data
Domain Logic - enforces domain logic attached to retrieving and manipulating the data
Mapping Logic - Transforms raw data from the resource interfacer into the data models
Resource Interfacing - actually calls resources to get or put data; does not implement domain logic
Data - the actual data that we'll be working with; a database or webservice
And finally there's the models themselves, which aren't really a layer. Think of them like datagrams that get passed around throughout the program.
And then each layer should consist of multiple classes that are each concerned about a specific data element, such as a post, a board, or a user. Each collection of layers that is concerned with a single data element or set of related data elements constitutes a module. Keeping to this setup will ensure a robust and resilient implementation that's easy to manage and make changes to.