|
Hammerite posted:By the way, I just thought to check the OP of this thread, and it contains a link to W3Schools' PHP coverage, which is not exactly great. Does anybody know whether Duz still posts? Yeah the W3 tutorials seem old as poo poo but if there are the best then I will go through. Just really love the codeacademy mini courses and instant review capabilities. Thanks though
|
# ? Oct 27, 2012 14:29 |
|
|
# ? Jun 5, 2024 05:50 |
|
thegasman2000 posted:Yeah the W3 tutorials seem old as poo poo but if there are the best then I will go through. Just really love the codeacademy mini courses and instant review capabilities. Thanks though No never use W3 Schools http://w3fools.com/
|
# ? Oct 27, 2012 15:30 |
|
musclecoder posted:No never use W3 Schools http://w3fools.com/ wow looking at w3fools was actually a bigger waste of my time than looking at w3schools
|
# ? Oct 27, 2012 15:54 |
|
A hamburger? posted:wow looking at w3fools was actually a bigger waste of my time than looking at w3schools Huh? W3Schools is poo poo.
|
# ? Oct 27, 2012 16:23 |
|
thegasman2000 posted:Yeah the W3 tutorials seem old as poo poo but if there are the best then I will go through. Just really love the codeacademy mini courses and instant review capabilities. Thanks though I haven't looked in depth at W3Schools's PHP coverage but I did flick through their "PHP + MySQL" pages (as I said, that sort of material can be a good pointer as to whether a learning resource is any good) and it's quite bad. (If you are interested in why, look up "SQL injection", then look over W3Schools's example queries in those pages and see if you can identify the problems they have.) If you will be manipulating databases at all then look for other resources. You might try this.
|
# ? Oct 27, 2012 18:51 |
|
I've been reading lately about CSFR attacks on your form pages and creating tokens or something to prevent it? Does anyone know of a good article that explains what exactly it is, how it works, and how to prevent it (using PHP best practices)? Also, are CSFR's limited to cross-site, or can they be across your own pages or even on the same page? For example: Let's say I have a simple app that allows CRUD on managing a list of books. Could a user not load up a book, see the hidden input for the book id, change it via addons or whatever the gently caress they use to POST fake data so that that form, even though it loaded one book, when you update it changes a different book because you changed the id for the POST request? Hopefully what I just said makes sense.
|
# ? Oct 30, 2012 18:58 |
|
IT Guy posted:I've been reading lately about CSFR attacks on your form pages and creating tokens or something to prevent it? Does anyone know of a good article that explains what exactly it is, how it works, and how to prevent it (using PHP best practices)? A CSRF (cross-site request forgery) is an attack that lets third-party sites run commands on behalf of a user on your site. An overly simplified example: You are a bank, and you have a form that allows you to transfer money to another person. The form is invoked by the following URL: /transfer.php?to=IntendedUser&amount=100 . A third party site can rewrite that URL to be ?to=EvilHacker&amount=1000, drop it in an iframe, and embed it in a page with high traffic or an advertisement. The way it works is that if your cookie is still active on the bank site, the iframe loads the page and sends the request without the user knowing, which harvests $1000 from their account. The way to defeat these requests is to include a token along with the request. E.g.: /transfer.php?to=IntendedUser&amount=100&csrf_token=skdfhslkfhsdahfds . The token is stored in the user's session, server side, and is included in the form when it's rendered to the user. When the form is submitted by the user, the submitted token is compared to the value in the session. If they match, the request is legit and the transfer goes through. A person designing an IFRAME with the malicious request cannot predict the contents of that token, and as such cannot use it to execute commands on the behalf of another user.
|
# ? Oct 30, 2012 19:20 |
|
Glory of Arioch posted:A CSRF (cross-site request forgery) is an attack that lets third-party sites run commands on behalf of a user on your site. Interesting. I guess what I was talking about isn't really CSRF then. So, how do you stop users from editing your forms or hidden IDs and submitting fake data? Basically, how to I make sure they are actually using the form and not using addons to POST fake data?
|
# ? Oct 30, 2012 19:37 |
|
IT Guy posted:Interesting. I guess what I was talking about isn't really CSRF then. Give us an example of what you are worried about users doing. I saw your post above but don't completely follow.
|
# ? Oct 30, 2012 19:43 |
|
IT Guy posted:Interesting. I guess what I was talking about isn't really CSRF then. You don't. You have no control over what input the user submits. What you can do, however, is perform validation on the server side to reject any input that is not what you want. For example, if a user should only have the ability to edit his or her posts, double check in the server's form handler that the post they are trying to edit actually belongs to the user in question.
|
# ? Oct 30, 2012 19:49 |
|
Glory of Arioch posted:You don't. You have no control over what input the user submits. What you can do, however, is perform validation on the server side to reject any input that is not what you want. For example, if a user should only have the ability to edit his or her posts, double check in the server's form handler that the post they are trying to edit actually belongs to the user in question. For my current app, this requires like 10 different SQL queries to ensure validation. Is this fine? How many queries is "too many"?
|
# ? Oct 30, 2012 20:05 |
|
IT Guy posted:For my current app, this requires like 10 different SQL queries to ensure validation. Is this fine? How many queries is "too many"? It depends on the application, the complexity of the queries, and how much traffic you get. There's no right answer. However, form validation is exceedingly important, so you need to do it.
|
# ? Oct 30, 2012 20:08 |
|
IT Guy posted:For my current app, this requires like 10 different SQL queries to ensure validation. Is this fine? How many queries is "too many"? Before I optimized it, logging into our site fired off several thousand queries. It still took less than a second to log in.
|
# ? Oct 30, 2012 20:30 |
|
Golbez posted:Before I optimized it, logging into our site fired off several thousand queries. It still took less than a second to log in. Wow. Yeah, I'm not familiar with gigantic databases. Mine right now is 30ish tables which I thought was big. I can join everything together with about 10 queries.
|
# ? Oct 30, 2012 20:32 |
|
The rule is generally, don't worry about something being slow until it's actually slow. Also known as "Don't pre-emptively optimize."
|
# ? Oct 30, 2012 20:36 |
|
It's also good to remember that it's not how many queries, but what type and on what data. I've written queries before that took upwards of 5 seconds to run (and were difficult as hell to debug the issue with). You'll know when it's time to optimize.
|
# ? Oct 30, 2012 20:38 |
|
Looking for a bit of best-practise knowledge if anyone can help. I'm using the CI framework and have a user model which I've added an edit_user() function to which is a simple update function using the current object's properties. Here's my class and constructor... php:<? class User_model extends CI_Model { var $user_id; var $user_name; var $user_email; var $user_password; var $user_activation_code; var $user_activated; var $user_banned; var $user_banned_reason; var $user_created; var $user_amended; /** * User_model::__construct() * * Load database driver and assign default values for user */ function __construct($user_id = NULL, $user_name = NULL, $user_email = NULL) { parent::__construct(); $this->load->database(); $this->user_activated = 0; $this->user_banned = 0; $this->user_banned_reason = ''; if(!empty($user_id) OR !empty($user_name) OR !empty($user_email)) { if(!empty($user_id)) { $user = $this->get_user_by_id($user_id); } elseif(!empty($user_name)) { $user = $this->get_user_by_name($user_name); } elseif(!empty($user_email)) { echo $user_email; $user = $this->get_user_by_email($user_email); } $this->user_id = $user->user_id; $this->user_name = $user->user_name; $this->user_email = $user->user_email; $this->user_password = $user->user_password; $this->user_activation_code = $user->user_activation_code; $this->user_activated = $user->user_activated; $this->user_banned = $user->user_banned; $this->user_banned_reason = $user->user_banned_reason; $this->user_created = $user->user_created; $this->user_amended = $user->user_amended; } } ?> Here's my get_ functions and edit_user() function. php:<? /** * User_model::get_user_by_id() * * Get user object for user_id * * @param int $user_id * @return user */ function get_user_by_id($user_id) { $query = $this->db->get_where('user',array('user_id' => $user_id)); return $query->row(); } /** * User_model::get_user_by_name() * * Get user object for user_name * * @param int $user_name * @return user */ function get_user_by_name($user_name) { $query = $this->db->get_where('user',array('user_name' => $user_name)); return $query->row(); } /** * User_model::get_user_by_email() * * Get user object for user_email * * @param int $user_email * @return user */ function get_user_by_email($user_email) { $query = $this->db->get_where('user',array('user_email' => $user_email)); return $query->row(); } /** * User_model::edit_user() * * Update record in user table * */ function edit_user() { $this->user_amended = date("Y-m-d H:i:s"); $this->db->update('user',$this,array('user_id'=>$this->user_id)); } ?> php:<? $user = new $this->user_model(NULL,NULL,$this->input->post('user_email')); if(empty($user)) { show_error('The email address you entered is invalid!'); } else { $new_password = $this->_generate_password(8); $user->user_password = md5($new_password); $user->edit_user(); echo 'Your new password ' . $user->user_password . ' has been emailed to ' . $user->user_email; } ?> Any pointers?
|
# ? Oct 30, 2012 22:42 |
|
Also, someone was asking for a PHPStorm IDE review. I've been swapping between Storm and PHP Designer 8 for the last few weeks and have decided to stick with Designer. In a nutshell, it seems Storm supports Symfony2 and Designer supports CI. If you're not using either I'd maybe lean to Storm because it seems more fully featured but it is a lot slower (on bootup and general UI) compared to Designer. Designer feels a lot more lightweight. I'd say the debugging is better in Storm though. Both are good options.
|
# ? Oct 30, 2012 22:46 |
|
I'm trying to find substantive comparisons of frameworks and am coming up short; does anyone know of a place with reviews that go in depth, instead of a meaningless "this is a checklist of what this framework has!" This is not a decision I want to make twice so I want to have all the information before going in.
|
# ? Oct 30, 2012 22:52 |
|
I was in a similar situation recently and found the best approach is to do a starter tutorial in each and go from there. Personally I've settled for CI though and am finding it fantastic to work with as a relative beginner to MVC. The documentation and community are great. It's relatively easy to get your head around how everything hangs together and it does a lot of stuff for you without having to write lines and lines of code. I couldn't get on with Symfony2 as it seemed a lot more complicated after using CI. And the same goes for Zend but tenfold.
|
# ? Oct 30, 2012 22:59 |
|
Sorry, one final Code Igniter question for those who use it. I've created an Auth library which deals with my login/logout stuff. I'm auto-loading this library and in each controller where it's required I've got the following code in the constructor. php:<? protected $my_user; /** * User::__construct() * * Load user_model and helpers * */ public function __construct() { parent::__construct(); $this->load->model('user_model'); $data = new stdClass(); $data->is_logged_in = FALSE; if($this->auth->logged_in()) { $this->my_user = $this->auth->user(); //set global user and load into all views $data->my_user = $this->my_user; $data->is_logged_in = TRUE; } $this->load->vars($data); } ?>
|
# ? Oct 30, 2012 23:54 |
|
Glory of Arioch posted:You don't. You have no control over what input the user submits. What you can do, however, is perform validation on the server side to reject any input that is not what you want. For example, if a user should only have the ability to edit his or her posts, double check in the server's form handler that the post they are trying to edit actually belongs to the user in question. A while ago I came up with a method of validating the authenticity of HTML form data submitted via HTTP POST by including a token with the form as a hidden input element. The token would be generated on request by combining a plain text string and a cipher text string which would be created by encrypting the plain text string using a symmetric-key block cipher. The cipher key would be pre-defined and only known by the server. When HTML form data is submitted to the server via HTTP POST it will look for the submitted token, split it into its plain and cipher text portions, encrypt the plain text portion using the same cipher key and then compare the resulting cipher text with the cipher text provided in the token. If they match then the form data is authentic. Sorry if that doesn't make sense. Here is a rough implementation of what I'm talking about (Note I just knocked this up in a few minutes and haven't actually tested it): (Oops, sorry about any table breakage. I've uploaded the code to Pastebin here: http://pastebin.com/1Z8yEVvF.) So yeah ideally submission of the token to the server would be made mandatory which means that the server should only accept HTML form data which is submitted from pages you control. The only weakness with this system is if the cipher key used to generate the tokens is compromised (Also I guess key derivation might be an issue depending on the strength of the cipher key and the block cipher used). Edit: I am a gigantic moron, please ignore this post and read ShoulderDaemon's response below. Pile Of Garbage fucked around with this message at 06:07 on Oct 31, 2012 |
# ? Oct 31, 2012 04:35 |
|
cheese-cube posted:A while ago I came up with a method of validating the authenticity of HTML form data submitted via HTTP POST by including a token with the form as a hidden input element. Aside from the fact that your crypto protocol is completely and laughably insecure, there's nothing stopping someone from fetching the HTML form, copying the hidden security token out of it, then submitting whatever else they want along with that security token. You aren't actually authenticating anything other than "they fetched the form at some point prior to sending me a request". Hell, in the code you pasted, you aren't even preventing them from simply fetching the token once and then just using the same token forever for all future requests they want to make. Don't design your own crypto protocols. You can't do it. Professional crypto people can't even design secure protocols on their own. Designing secure crypto protocols is one of the closest things there is in software engineering to an impossible task.
|
# ? Oct 31, 2012 05:06 |
|
You are right about malicious third-parties simply being able to fetch the token from the form and reuse it. I didn't consider that which is pretty darn idiotic of me and basically renders my script useless. Quite frankly I'm pretty embarrased about that post now however I'll leave it there as-is for posterity and as an example of what not to do.
|
# ? Oct 31, 2012 06:06 |
|
Am I right in thinking that: date("Y-m-t", strtotime("-1 month")) should always return the last day of the previous month? For some reason it's giving me a result of 2012-10-31 today (i.e.: today's date), instead of 2012-09-30.
|
# ? Oct 31, 2012 10:15 |
|
Quote-Unquote posted:Am I right in thinking that: code:
The Gripper fucked around with this message at 10:35 on Oct 31, 2012 |
# ? Oct 31, 2012 10:33 |
|
strtotime is giving you the 31st day after the start of September just fine. Yes, that's the 1st of October. If you explicitly specify a day in your strtotime (for example, "last day of last month"), it should work as you expect. Once you've got the last day of the month, use d to print out the day instead of t (which prints out the total number of days in the month). Using t is probably going to break for months where some of the days in the middle don't exist.
|
# ? Oct 31, 2012 10:37 |
|
D'oh, that makes sense. Thanks guys.
|
# ? Oct 31, 2012 10:49 |
|
Something like this works great for securing a form. It's very simple and gets the job done.php:<? function generate_token($type = "form") { $token = sha1(session_id() . ":secureform"); if ($type == "plain") { return $token; } if ($type == "link") { return "&token={$token}"; } if ($type == "form") { return "<input type=\"hidden\" name=\"token\" value=\"{$token}\" />"; } } function check_token() { if ($_REQUEST['token'] != generate_token("plain")) { exit("Invalid Token"); } } ?> DarkLotus fucked around with this message at 21:21 on Oct 31, 2012 |
# ? Oct 31, 2012 14:45 |
|
DarkLotus posted:Something like this works great for securing a form. It's very simple and gets the job done. How does this secure the form? The user needs to get to the form to get the token, sure, but can't then the session id be copied along with the token to an attack script?
|
# ? Oct 31, 2012 14:54 |
|
Quote-Unquote posted:Am I right in thinking that: Always do mktime() with a date of 1 for month math. Always. date('Y-m-t', mktime(0, 0, 0, date('n') - 1), 1);
|
# ? Oct 31, 2012 14:56 |
|
baquerd posted:How does this secure the form? The user needs to get to the form to get the token, sure, but can't then the session id be copied along with the token to an attack script? Sorry, its a good way to generate tokens for forms and links to protect against CSRF. It doesn't solve the issue of users submitting false form data that IT Guy was concerned with.
|
# ? Oct 31, 2012 15:18 |
|
DarkLotus posted:Sorry, its a good way to generate tokens for forms and links to protect against CSRF. It doesn't solve the issue of users submitting false form data that IT Guy was concerned with. Yeah, most of my work is on an intranet so CSRF attacks aren't really my concern, I was just originally confused about exactly what they were. I guess my solution is just going to be lots of form validation to ensure the integrity of the data.
|
# ? Oct 31, 2012 18:49 |
|
baquerd posted:How does this secure the form? The user needs to get to the form to get the token, sure, but can't then the session id be copied along with the token to an attack script? The idea is that because the token changes every time they look at the form, an attacker can't just POST random garbage somewhere else.
|
# ? Oct 31, 2012 18:53 |
|
Another common pattern (in addition to single-use tokens per protected form) is to generate a hash of any hidden fields in a specific order. At the minimum, validating that hash on submit will make sure that those fields weren't tampered with. Select menus should also be validated against their expected contents. The real dangers of CSRF are admin-side things. If you're truly worried about it, forcing the user to re-enter their password for certain actions is a sure-fire way to block CSRF while simultaneously irritating your users.
|
# ? Oct 31, 2012 18:54 |
|
IT Guy posted:Yeah, most of my work is on an intranet so CSRF attacks aren't really my concern, I was just originally confused about exactly what they were. You can <form action="http://intranet-host/" method="post"> from a Internet site
|
# ? Oct 31, 2012 19:11 |
|
Bradzor posted:The idea is that because the token changes every time they look at the form, an attacker can't just POST random garbage somewhere else. Why does it change every time they look at the form? Isn't the session id a constant stored as a client side cookie that can be spoofed and fairly static unless you change it on purpose? I don't really understand the current session methodology.
|
# ? Oct 31, 2012 19:26 |
|
baquerd posted:Why does it change every time they look at the form? Isn't the session id a constant stored as a client side cookie that can be spoofed and fairly static unless you change it on purpose? I don't really understand the current session methodology. You're thinking of the ID that identifies the session. We're talking about a check number that gets saved to the session. $_SESSION is server-side, it never goes to the cookie. Pseudocode: $CheckID = unique_id(); $_SESSION['form_check_id'] = $CheckID; echo '<input type="hidden" name="check_id" value="$CheckID">'; ... if ($_POST['check_id'] !== $_SESSION['form_check_id']): echo ""; This way, if they have opened the form with another/no session, or have opened a subsequent form, it will fail. Preventing session hijacking is another topic entirely.
|
# ? Oct 31, 2012 19:36 |
|
Golbez posted:You're thinking of the ID that identifies the session. We're talking about a check number that gets saved to the session. $_SESSION is server-side, it never goes to the cookie. In the example that DarkLotus provided and baquerd referenced, the token is a hash of session_id(), which is constant for the duration of the session.
|
# ? Oct 31, 2012 20:19 |
|
|
# ? Jun 5, 2024 05:50 |
|
DaTroof posted:In the example that DarkLotus provided and baquerd referenced, the token is a hash of session_id(), which is constant for the duration of the session. Oh, well yeah, that would seem to me to be bad form. Especially if it's something easily deciphered like that, "Hm this form key is always the SHA1 of my session ID!"
|
# ? Oct 31, 2012 20:26 |