From rainelemental at gmail.com Tue May 6 09:39:08 2014 From: rainelemental at gmail.com (Federico Ulfo) Date: Tue, 6 May 2014 09:39:08 -0400 Subject: [nycphp-talk] Logging best practices Message-ID: Hi PHPers, long time no see, at my current job we recently decided to unify the way we log cross repos and cross languages, our legacy code for logging is pretty diverse, we use different functions to log, some uses error_log other writes straight to file other to scribe, and many mix all the above. This is relatively good, because we don't miss a beat, everything is logged, the bad part is that our disk space is often an issue, so on top of log rotate we've to move the logs on backups, which are sparse as well. Scribe is pretty cool, because it store everything in one place, which then we move somewhere else to save disk space, again! We're considering to use syslog as common logging for all languages, mostly PHP, Java and Python (Scala, Perl, Ruby ...), so we can finally log with a standard format, e.g.: TIME - HOSTNAME PID [LOG LEVEL] MESSAGE For PHP we'll probably use Monolog, someone suggested to use it wrapped into helper functions such as sail_info(), sail_debug(), sail_error(), sail_warn(), I'm personally skeptical for this solution because not too maintainable, but I agree that Monolog is too verbose and quite ugly to remember. What's your experience with logging? Is there anything that you could suggesting to do and (especially) not to do when organizing the logs? I'll be happy to hear any of your comments. Thanks, Federico. -------------- next part -------------- An HTML attachment was scrubbed... URL: From garyamort at gmail.com Thu May 8 18:01:33 2014 From: garyamort at gmail.com (Gary Mort) Date: Thu, 08 May 2014 18:01:33 -0400 Subject: [nycphp-talk] Logging best practices, 1 of 2 In-Reply-To: References: Message-ID: <536BFEBD.3030600@gmail.com> On 05/06/2014 09:39 AM, Federico Ulfo wrote: > > Hi PHPers, > > ... > For PHP we'll probably use Monolog, someone suggested to use it > wrapped into helper functions such as sail_info(), sail_debug(), > sail_error(), sail_warn(), I'm personally skeptical for this solution > because not too maintainable, but I agree that Monolog is too verbose > and quite ugly to remember. > > What's your experience with logging? Is there anything that you could > suggesting to do and (especially) not to do when organizing the logs? I really don't like to directly use custom logging classes/functions. You become locked into a specific framework and switching to the new "flavor of the month" in the future is a large workload for little gain. For informational logging, I prefer to use the functions built in to PHP: user_error with E_USER_WARNING, E_USER_NOTICE, and E_USER_DEPRECATED. Your guaranteed that the function is /always/ available and there are a number of options on where to send the log messages. If you want to use a system like monolog, you can still do that while using the user_error function, simply use the set_error_handler function and you can route the error message to whatever flavor of the month logging class is popular. If you need more information then is easily contained in a string, then in your error handler you can use serialize it from the extra parameters or use $errcontext to get more information. **code** functionhandler($errno,$errstr,$errfile,$errline, $errcontext) { $errObject = new \StdClass; $errObject->msg = $errstr; $errObject->file = $errfile; $errObject->line = $errline; if (isset($errcontect['this']) { $errObject->classname = get_class($errcontect['this']); } $logMsg = json_encode($errObject); \Fancy\Schmancy\Logging\Tool::log($logMsg); return true; } **endcode** For ending program execution abrubtly, by the same token I prefer to use the tools built into PHP: user_error with E_USER_ERROR. Again you have all the options above. For libraries where I want to maintain flexibility, I prefer to combing information logging with throwing exceptions. That way the message is saved/logged regardless, and then whatever script is calling mine can either catch the error and recover, or not as is appropriate. Anytime there is a handler/wrapper option in PHP that can be used to provide the custom functionality I want, I prefer to use the use that. That way my PHP code is insulated from 'flavor of the month' and api changes - while at the same time a small initialization script allows me to make full use of them. -------------- next part -------------- An HTML attachment was scrubbed... URL: From garyamort at gmail.com Thu May 8 18:30:37 2014 From: garyamort at gmail.com (Gary Mort) Date: Thu, 08 May 2014 18:30:37 -0400 Subject: [nycphp-talk] Logging best practices, 2 of 2 In-Reply-To: References: Message-ID: <536C058D.50001@gmail.com> On 05/06/2014 09:39 AM, Federico Ulfo wrote: > We're considering to use syslog as common logging for all languages, > mostly PHP, Java and Python (Scala, Perl, Ruby ...), so we can finally > log with a standard format, e.g.: > TIME - HOSTNAME PID [LOG LEVEL] MESSAGE > > I prefer syslog to all other logging transports. Using syslog means you can save logs offsite[which is important if you ever need to do forensic security analysis. If all the log data is on the server and the server is compromised, the log data is compromised. Even if you archive it off, it can still be modified before that archive occurs]. Truthfully, I prefer rsyslog, not syslog - but from the PHP side they are the same thing. You can easily setup a Log Analyzer server to send all the data to, which provides you with the ability to tail/view your logs as your developing. And since Log Analyzer is written in PHP, you can change it to suite your purposes. http://loganalyzer.adiscon.com/ and http://www.rsyslog.com/ A common mistake I see in people implementing syslog logging is that they use direct connections to their syslog server. IE using monolog's StslogUdpHandler: https://github.com/Seldaek/monolog/blob/master/src/Monolog/Handler/SyslogUdpHandler.php To me, the whole point of using syslog/rsyslog is that it is FAST. Your app connects to a syslog server over a local socket and fires strings at it. If you connect to a /remote/ syslog server then every single message you log will slow down your app. I've seen some weird UDP implementations that wait for some form of ack from the network device that the message has been queued. Or if it is important to you, it's possible to use tcp to provide guaranteed delivery. It does take a bit more configuration, but with a local rsyslog server you can setup extremely simple 'forward every message to the remote server AND log it locally' to complex conditional logs. I like to set it up to log to local files in a tmpfs directory, and then purge the logs every couple of hours. That gives me local access to the logs for development/debugging - while I have the remote server for archives. Putting it on a tmpfs drive means that they get stored in memory instead of on the hard drive so there is no issue of slowing down the server by making it write log messages to a hard drive. Note: just because your using syslog does not mean you are locked into the limitation of message being a single string. You can json_encode anything into a string - rsyslog has a number of plugins to explode that data into fields and then save them into a database or such. Or if you don't want to roll your own, Papertrail provides access via the syslog protocol and already handles json. https://papertrailapp.com/ Sometimes it's better to just pay someone else 20-40$ a month and let them deal with the headaches. And with syslog, your not locked into a vendor. You could send your log files to papertrail, save them onto a local tmpfs drive, AND send them to a centralized garbage heap syslog server filled with cheap drives and no real reporting/access policy. IE keep a copy of the data archived forever 'just in case' but don't bother setting up an interface for it until the expense of paying a provider like papertrail grows large enough to justify bringing it in house. From noreply+164352707 at hotornot.com Sun May 11 15:02:29 2014 From: noreply+164352707 at hotornot.com (Charles Vasquez) Date: Sun, 11 May 2014 19:02:29 +0000 Subject: [nycphp-talk] =?utf-8?q?=E2=98=85_Your_friends_think_you=27re_Hot!?= Message-ID: <20140511190229.5A856AF003D@cluster2012.monopost.com> An HTML attachment was scrubbed... URL: From ioplex at gmail.com Sun May 18 01:43:01 2014 From: ioplex at gmail.com (Michael B Allen) Date: Sun, 18 May 2014 01:43:01 -0400 Subject: [nycphp-talk] Proper Form Processing Techniques Message-ID: Hi All, Occasionally I need to do a little web programming and I must admit after almost 2 decades I still find myself searching for a better way to handle HTML forms. I blame this mostly on the W3C's invalid assumption that HTML is for rendering documents and not building applications. But putting blame aside, I would like to ask the list to share their best form processing techniques. There's a particular scenario that bugs me about forms which is that it is increasingly rare that you have a bunch of fields with just a submit button. There are usually multiple possible operations that build up and modify the data before it's submitted. A good example of this is a shopping cart where there is one form but commands for removing and item, updating quantities, applying a discount code and submitting the cart. But the form only has one action. Currently I've been just using hidden fields and then call a javascript function to fill in the hidden fields with the desired data for the particular command and submit the form. For example: ...
... Remove ... Update Qty. ...
So how would you do this sort of thing? My current technique seems a little hackish because I'm using the hidden form element "cmd" to modify the action. In practice it might seem purer to modify the action to call /purchase/remove or /purchase/update for use with modern routing on the server. Can you point me to a site that you think illustrates good form processing technique? Note that I'm not really interested in frameworks and third party components. This cart example is just one example. I'm really trying to arrive at a proper form processing technique in general. So I'm not really interested in "Just use Acme Cart 2000" sorts of answers. Ideas? Mike -- Michael B Allen http://www.ioplex.com/ From ramons at gmx.net Sun May 18 07:52:59 2014 From: ramons at gmx.net (David Krings) Date: Sun, 18 May 2014 07:52:59 -0400 Subject: [nycphp-talk] Proper Form Processing Techniques In-Reply-To: References: Message-ID: <53789F1B.1000105@gmx.net> On 5/18/2014 1:43 AM, Michael B Allen wrote: > Hi All, > > Occasionally I need to do a little web programming and I must admit > after almost 2 decades I still find myself searching for a better way > to handle HTML forms. I blame this mostly on the W3C's invalid > assumption that HTML is for rendering documents and not building > applications. But putting blame aside, I would like to ask the list to > share their best form processing techniques. > > There's a particular scenario that bugs me about forms which is that > it is increasingly rare that you have a bunch of fields with just a > submit button. There are usually multiple possible operations that > build up and modify the data before it's submitted. A good example of > this is a shopping cart where there is one form but commands for > removing and item, updating quantities, applying a discount code and > submitting the cart. But the form only has one action. > > Currently I've been just using hidden fields and then call a > javascript function to fill in the hidden fields with the desired data > for the particular command and submit the form. > > Ideas? > Hi! The only ideas I have is to have items listed in divs and then use js to hide the div if the action on that item is 'remove'. Other than that, rather than deal with hidden fields that really aren't that hidden write everything you need to know to the session cookie. HTML5 offers even more options now. Not sure if that is a better way, but it is at least a different way and maybe it helps. HTML was never intended as application programming language and I don't see that as a problem. You do want to separate business logic from presentation even when it often blends together using javascript. Even js is a cheat because browser based apps are by design client/server apps. The client requests and the server responds. I agree that js makes pages more usable and allows for pretty neat stuff, but it breaks the underlying model and often enough I encounter problems because the server has no idea what the client is doing, sometimes even so much so that the server lets the session time out although the user is actively using the app, but all interactions are client side. David From bill.patterson1 at comcast.net Sun May 18 14:23:41 2014 From: bill.patterson1 at comcast.net (Bill Patterson) Date: Sun, 18 May 2014 14:23:41 -0400 Subject: [nycphp-talk] Proper Form Processing Techniques In-Reply-To: References: Message-ID: <5378FAAD.8070705@comcast.net> My favorite technique is to look at form processing as a set of orthogonal descriptions. In the case of a validating data entry form the first description is the description of the form itself, which I like in XML, and regardless you could use your own notation. The second description is orthogonal to the first and is the description of the processes run against the form, data entry, data validation, data submission, and, perhaps, information rendering. (Unfortunately I know of no non-proprietary sites to reference.) Bill On 5/18/2014 1:43 AM, Michael B Allen wrote: > Hi All, > > Occasionally I need to do a little web programming and I must admit > after almost 2 decades I still find myself searching for a better way > to handle HTML forms. I blame this mostly on the W3C's invalid > assumption that HTML is for rendering documents and not building > applications. But putting blame aside, I would like to ask the list to > share their best form processing techniques. > > There's a particular scenario that bugs me about forms which is that > it is increasingly rare that you have a bunch of fields with just a > submit button. There are usually multiple possible operations that > build up and modify the data before it's submitted. A good example of > this is a shopping cart where there is one form but commands for > removing and item, updating quantities, applying a discount code and > submitting the cart. But the form only has one action. > > Currently I've been just using hidden fields and then call a > javascript function to fill in the hidden fields with the desired data > for the particular command and submit the form. > > For example: > > ... > > > >
> > > > ... > > Remove > ... > Update Qty. > ... >
> > So how would you do this sort of thing? > > My current technique seems a little hackish because I'm using the > hidden form element "cmd" to modify the action. In practice it might > seem purer to modify the action to call /purchase/remove or > /purchase/update for use with modern routing on the server. > > Can you point me to a site that you think illustrates good form > processing technique? > > Note that I'm not really interested in frameworks and third party > components. This cart example is just one example. I'm really trying > to arrive at a proper form processing technique in general. So I'm not > really interested in "Just use Acme Cart 2000" sorts of answers. > > Ideas? > > Mike > From ajai at bitblit.net Mon May 19 00:55:03 2014 From: ajai at bitblit.net (Ajai Khattri) Date: Mon, 19 May 2014 00:55:03 -0400 Subject: [nycphp-talk] Proper Form Processing Techniques In-Reply-To: <53789F1B.1000105@gmx.net> References: <53789F1B.1000105@gmx.net> Message-ID: <20140519045503.GA10581@www.bitblit.net> On Sun, May 18, 2014 at 07:52:59AM -0400, David Krings wrote: > I agree that js makes pages more usable and > allows for pretty neat stuff, but it breaks the underlying model and often > enough I encounter problems because the server has no idea what the client is > doing, sometimes even so much so that the server lets the session time out > although the user is actively using the app, but all interactions are client > side. Recent JS frameworks have been addressing this, go look at AngularJS... -- Aj. FaceBook: facebook.com/ajaikhattri EnoLand: http://flip.it/Gig0n From garyamort at gmail.com Mon May 19 13:40:33 2014 From: garyamort at gmail.com (Gary Mort) Date: Mon, 19 May 2014 13:40:33 -0400 Subject: [nycphp-talk] Proper Form Processing Techniques In-Reply-To: References: Message-ID: <537A4211.4010105@gmail.com> On 05/18/2014 01:43 AM, Michael B Allen wrote: > Hi All, > > > My current technique seems a little hackish because I'm using the > hidden form element "cmd" to modify the action. In practice it might > seem purer to modify the action to call /purchase/remove or > /purchase/update for use with modern routing on the server. Whether you are adding an item, removing an item, adding a code, or whatnot - all those actions are based on "updating" the order. There is no need to do "different" processing for each one, you can do all of that processing in one process. IE: "removing" an item is equivalent to setting the item quantity to 0 or less[just for that joker who decides to put -1000 in the quantity field and force a submit]. So for every item that is submitted on the form, you can check the quantities, if zero or negative then if the product id is in the order list, remove it. If positive, then either add or update the quantity. If an item currently in the cart was not submitted, leave it alone. This allows for submission updates that only change a single item, delete items, add multiple items, etc. Coupon codes work in the same manner. If there is no coupon code submitted, then you use the coupon code currently stored in the session. If a coupon code is added, then add it to the session. If there is an existing coupon code and a new one was entered, decide what you want to do[ie you might allow multiple codes, you might not.... ] Basically each of these steps can be encapsulated into your class and processed in one step: Class cart function updateItems(....$itemInfoList); function updateCoupon(...$couponInfo); function update() { // get the info submitted $this->updateItems($itemList); $this->updateCoupon($coupon); .... } Up to you how you want to handle error checking - check between each step, check at the end, etc. If storing data into an SQL database, you can use transactions to undo updates on an error. Technically, you really should use PUT instead of POST, since POST implies all the information is on the form, wheras PUT implies that your are only submitting changes. Not relevant is DELETE. For MOST "deletions" your really doing an update. IE your not "deleting" an item from the cart, you are updating the cart and removing that item. Even if you "delete" the entire cart, all visitors have a cart, what your really doing is "emptying" the cart. From ioplex at gmail.com Tue May 20 04:24:38 2014 From: ioplex at gmail.com (Michael B Allen) Date: Tue, 20 May 2014 04:24:38 -0400 Subject: [nycphp-talk] Proper Form Processing Techniques In-Reply-To: <537A4211.4010105@gmail.com> References: <537A4211.4010105@gmail.com> Message-ID: On Mon, May 19, 2014 at 1:40 PM, Gary Mort wrote: > > On 05/18/2014 01:43 AM, Michael B Allen wrote: >> >> Hi All, >> >> >> My current technique seems a little hackish because I'm using the >> hidden form element "cmd" to modify the action. In practice it might >> seem purer to modify the action to call /purchase/remove or >> /purchase/update for use with modern routing on the server. > > > Whether you are adding an item, removing an item, adding a code, or whatnot > - all those actions are based on "updating" the order. > > There is no need to do "different" processing for each one, you can do all > of that processing in one process. > > IE: "removing" an item is equivalent to setting the item quantity to 0 or > less[just for that joker who decides to put -1000 in the quantity field and > force a submit]. So for every item that is submitted on the form, you can > check the quantities, if zero or negative then if the product id is in the > order list, remove it. > > If positive, then either add or update the quantity. > > If an item currently in the cart was not submitted, leave it alone. > > This allows for submission updates that only change a single item, delete > items, add multiple items, etc. Hi All, I actually started out doing what you describe but I thought the server side code started to get a little messy so I thought I would break things up into add, remove, applyCode and so on. As for other's suggestions about storing state on the client by what is ultimately manipulating the DOM with JavaScript, I can see how that could be used to create sophisticated UI elements. But I don't think I would ever put any state on the client that I couldn't accept losing at any moment (e.g. as I type this, gmail is periodically saving this message with async requests). Even storing stuff in a cookie seems dubious for a shopping cart. I think I will just commit each change to the DB so that user's can be confident that what they see is actually in the DB. In general it sounds like there are no new techniques that are obviously superior to the conventional form processing methods that have been used for decades. So I will carry on with the usual technique even if it does seem a little hackish. Thanks, Mike From ramons at gmx.net Tue May 20 07:39:36 2014 From: ramons at gmx.net (David Krings) Date: Tue, 20 May 2014 07:39:36 -0400 Subject: [nycphp-talk] Proper Form Processing Techniques In-Reply-To: References: <537A4211.4010105@gmail.com> Message-ID: <537B3EF8.3050809@gmx.net> On 5/20/2014 4:24 AM, Michael B Allen wrote: > As for other's suggestions about storing state on the client by what > is ultimately manipulating the DOM with JavaScript, I can see how that > could be used to create sophisticated UI elements. But I don't think I > would ever put any state on the client that I couldn't accept losing > at any moment (e.g. as I type this, gmail is periodically saving this > message with async requests). Even storing stuff in a cookie seems > dubious for a shopping cart. I think I will just commit each change to > the DB so that user's can be confident that what they see is actually > in the DB. Hi! I understand your concern, but you are working on a true client/server based application (browser apps are nothing else). So until anything resides on the server you don't have it. Async requests are one option, but what does the server code do with half of an order? And what do you do when the user clicks the 'Buy stuff' button sending the final form submission? That step is as likely to fail or succeed as any other. And once you get the final submission you need to have the server clean up any of the partial saves, although that effort could be minimized by simply flagging the order record as incomplete until the final submission comes in. In the current state of technology I'd be more worried about the connection between client and server than the client or server themselves. Unless the user uses Firefox 29 the chance of losing stuff through crashes are slim to none. I'd focus on getting the cart in place storing items locally and then sending the order in one swoosh over. Yes, that risks that the user may lose stuff halfway through when their end does not behave, but I found that to be a rather rare occasion. In return you will reduce the client/server traffic and hits against the database which both are quite costly. Also keep in mind that there is still a substantial number of folks on dialup or at least slow connections, but that depends on the target audience for your store. As far as the DOM manipulation with JS, I see that commonly done in enterprise grade browser based apps just for the sake of distributing computing tasks. Five or ten years ago that may have been different, but by now clients are running on generally beefy boxes and are very fast in executing JS. And now you even have access to local storage. So why not make use of that and bother the server with only that stuff that truly matters in the end? That is the only way to scale, I mean aside from buying bigger servers with bigger pipes. Just my 2? David From garyamort at gmail.com Wed May 21 11:09:33 2014 From: garyamort at gmail.com (Gary Mort) Date: Wed, 21 May 2014 11:09:33 -0400 Subject: [nycphp-talk] Promote Secure Coding Message-ID: <537CC1AD.50102@gmail.com> I was looking at a tutorial written in this century for PHP programming, and I had steam come out of my ears. Even in this day and age, so called PHP 'experts' still write tutorials where they create a simple hello world script which uses: $name = $_GET['name']; The concept of using the simple filter_input() function is not addressed in almost any tutorials, and those that do address it don't bother untill the second half of the book. I understand why they do this. Explaining all the intricacies of filter_input is an advanced topic. Moreover, using $_GET and $_POST make it very easy for instructional purposes to provide visual cues to the student for where this data comes from. Never the less, since we can create closure's in PHP and bind them to variables, it's a simple matter to use an anonymous function bound to $get and still maintain clarity. It can even be bound to $_GET so all they need to do is change [] to ()! So I wanted some feedback on the wording of the following to promote using 4 little lines of code to reduce PHP security issues: ## Do not do as they do As you learn how to program in PHP you will find almost all instructional tutorials as of 2014 do you a grave injustice. They teach you how to write dangerous, hackable, insecure PHP code. Since I can't wave a magic wand and make all those tutorials fix themselves, I have decided to instead provide you with a simple way to not let them do this to you. For any tutorial which ever tells you to get data submitted by a user by using the $_GET superglobal variable, you can perform a simple substitution: If they say: $exampleVariable = $_GET['exampleVariable']; You should use: $exampleVariable = $get('examplevariable); This is a small change that looks similar visually, so it makes it easy for you to substitute. Instead of getting the data from an array, you are getting the data using a function. Now in addition to the above, you will ALSO need to create this function. So at the top of any PHP file where you will be using this function, simple add the following 4 lines: // FIXME: replace this with a more complete data sanitizing script if isset($_GET) { unset($_GET); } // Force yourself not to use the global variable $get = function($varName) { return filter_input(INPUT_GET, $varName, FILTER_SANITIZE_STRING); } ## What this does // FIXME: replace this with a more complete data sanitizing script This is a PHP comment, it is not executable code. This is simply a notation to remind you in the future if you are using this file for a production website, to go back and replace this code with more appropriate and secure code. if isset($_GET) { unset($_GET); } // Force yourself not to use the global variable This line is to force you not use the $_GET array by deleting it. That way if you cut and paste code from a tutorial, you won't accidentally introduce security issues if you forget to make the neccessary changes. $get = function($varName) { return filter_input(INPUT_GET, $varName, FILTER_SANITIZE_STRING); } These 2 lines create a function to remove any HTML tags from a query string variable and return it. The function is a special PHP construct called a closure, which you can learn about later, which allows it to be refereneced by a variable. The purpose of using this odd construct is that it allows you to reuse these 2 lines of code multiple times in a PHP application without having to worry about duplicate function names. The filter_input is a PHP function which provides a create deal more security options then just the one I have used here. It is up to you to learn about and use those options appropriately. What I have included here is the bare minimum to provide some basic security AND to allow you to easily increase your security incremementally. For example, instead of having to rewrite every single PHP program you write in the beginning, you merely need to search for all the FIXME strings and change filter_input(INPUT_GET, $varName, FILTER_SANITIZE_STRING) to something more appropriate for your specific needs. -------------- next part -------------- An HTML attachment was scrubbed... URL: From daimmo at gmail.com Wed May 21 11:44:29 2014 From: daimmo at gmail.com (Pierpaolo D'Aimmo) Date: Wed, 21 May 2014 11:44:29 -0400 Subject: [nycphp-talk] Promote Secure Coding In-Reply-To: <537CC1AD.50102@gmail.com> References: <537CC1AD.50102@gmail.com> Message-ID: Interesting, thank you for the contribution. Same rules can be applied to $_REQUEST and $_POST, but I guess you think that's already clear from what you write in the last comments. Unfortunately, many people I think just want ready-made functions to copy and paste. You can make it more complete or be more clear in the "FIXME" line. Also, at least comments shouldn't be self-explained when not talking about them. Something like: //FIXME: This code is just an example, it's not complete, don't use it, just learn what it does and implement something that suit your real needs. // You may want to apply it to other variables as well, or even not use it at all (in some special cases.) (By the way, hi all. I think this is my first post on this list after years of random reading.) Pierpaolo D'Aimmo +1 201 892 1270 daimmo at gmail.com On Wed, May 21, 2014 at 11:09 AM, Gary Mort wrote: > I was looking at a tutorial written in this century for PHP programming, > and I had steam come out of my ears. > > Even in this day and age, so called PHP 'experts' still write tutorials > where they create a simple hello world script which uses: > > $name = $_GET['name']; > > The concept of using the simple filter_input() function is not addressed > in almost any tutorials, and those that do address it don't bother untill > the second half of the book. > > I understand why they do this. Explaining all the intricacies of > filter_input is an advanced topic. Moreover, using $_GET and $_POST make > it very easy for instructional purposes to provide visual cues to the > student for where this data comes from. > > Never the less, since we can create closure's in PHP and bind them to > variables, it's a simple matter to use an anonymous function bound to $get > and still maintain clarity. It can even be bound to $_GET so all they need > to do is change [] to ()! > > So I wanted some feedback on the wording of the following to promote using > 4 little lines of code to reduce PHP security issues: > > ## Do not do as they doAs you learn how to program in PHP you will find almost all instructional tutorials as of 2014 do you a grave injustice. They teach you how to write dangerous, hackable, insecure PHP code. > > Since I can't wave a magic wand and make all those tutorials fix themselves, I have decided to instead provide you with a simple way to not let them do this to you. > > For any tutorial which ever tells you to get data submitted by a user by using the $_GET superglobal variable, you can perform a simple substitution: > > If they say: > $exampleVariable = $_GET['exampleVariable']; > > You should use: > $exampleVariable = $get('examplevariable); > > This is a small change that looks similar visually, so it makes it easy for you to substitute. Instead of getting the data from an array, you are getting the data using a function. > > Now in addition to the above, you will ALSO need to create this function. So at the top of any PHP file where you will be using this function, simple add the following 4 lines: > > > // FIXME: replace this with a more complete data sanitizing script > if isset($_GET) { unset($_GET); } // Force yourself not to use the global variable > $get = function($varName) { > return filter_input(INPUT_GET, $varName, FILTER_SANITIZE_STRING); } > > ## What this does > // FIXME: replace this with a more complete data sanitizing script > This is a PHP comment, it is not executable code. This is simply a notation to remind you in the future if you are using this file for a production website, to go back and replace this code with more appropriate and secure code. > > if isset($_GET) { unset($_GET); } // Force yourself not to use the global variable > This line is to force you not use the $_GET array by deleting it. That way if you cut and paste code from a tutorial, you won't accidentally introduce security issues if you forget to make the neccessary changes. > > > $get = function($varName) { > return filter_input(INPUT_GET, $varName, FILTER_SANITIZE_STRING); } > > These 2 lines create a function to remove any HTML tags from a query string variable and return it. The function is a special PHP construct called a closure, which you can learn about later, which allows it to be refereneced by a variable. The purpose of using this odd construct is that it allows you to reuse these 2 lines of code multiple times in a PHP application without having to worry about duplicate function names. > > The filter_input is a PHP function which provides a create deal more security options then just the one I have used here. It is up to you to learn about and use those options appropriately. What I have included here is the bare minimum to provide some basic security AND to allow you to easily increase your security incremementally. For example, instead of having to rewrite every single PHP program you write in the beginning, you merely need to search for all the FIXME strings and change filter_input(INPUT_GET, $varName, FILTER_SANITIZE_STRING) to something more appropriate for your specific needs. > > > > _______________________________________________ > New York PHP User Group Community Talk Mailing List > http://lists.nyphp.org/mailman/listinfo/talk > > http://www.nyphp.org/show-participation > -------------- next part -------------- An HTML attachment was scrubbed... URL: From garyamort at gmail.com Wed May 21 13:13:08 2014 From: garyamort at gmail.com (Gary Mort) Date: Wed, 21 May 2014 13:13:08 -0400 Subject: [nycphp-talk] Promote Secure Coding In-Reply-To: References: <537CC1AD.50102@gmail.com> Message-ID: <537CDEA4.3090409@gmail.com> On 05/21/2014 11:44 AM, Pierpaolo D'Aimmo wrote: > Interesting, thank you for the contribution. > Same rules can be applied to $_REQUEST and $_POST, but I guess you > think that's already clear from what you write in the last comments. > Unfortunately, many people I think just want ready-made functions to > copy and paste. I want to create those as seperate articles and then crosslink them all. Yes, the idea is purely for people who are going to cut and paste code. IE all of this would be much better to declare once somewhere rather then in every single file - but that all requires at least 3 or 4 lessons in programming PHP before you get to that point. $_REQUEST is special in that there is no input stream for it, http://us1.php.net/manual/en/function.filter-input.php So a $_REQUEST filter either has to reimplement the GPC logic OR it can be done by calling filter_var($_REQUEST[$varName], $filter) - both of which are not ideal. I know that I at least like to pretend I think I know what code I'm cutting and pasting into my programs does so the whole GPC testing logic will look confusing. Wheras using the $_REQUEST variable means you can't unset it for safety. What I really like about using closures is that it becomes novice friendly. If instead I had written: function get($varName = '') { return filter_input(INPUT_GET, $varName, FILTER_SANITIZE_STRING); } Functionally it performs the same, but once the junior programmer starts using multiple files, it will break if it is used in multiple files. As an experienced programmer, $myvar = $_GET['myvar']; and $myvar = filter_input(INPUT_GET, 'myvar', FILTER_SANITIZE_STRING); Those 2 lines read the same to me. The second line reads as "I am explicitly filtering the data for my needs" while the first line reads as "This is just an example and don't use this in real code". But beginners aren't going to see that. And it really frustrates me because PHP is such a rich language that it can be used by people who have taken a short course on html as well as programmers. So I feel that we[the PHP community] are at fault for insecure PHP programs written in the past 10 years. By not providing and promoting a simple means for novices to write more secure code - we allow it to prolifigate. The secretary updating the company website for a small business is not going to bother to go past lesson 3 or 4 when she is told to add an input field for subject on the contact form. She will go as far as she needs to figure out she can add $subject = $_GET['subject'] and then be done. > You can make it more complete or be more clear in the "FIXME" line. > Also, at least comments shouldn't be self-explained when not talking > about them. > Something like: > //FIXME: This code is just an example, it's not complete, don't use > it, just learn what it does and implement something that suit your > real needs. > // You may want to apply it to other variables as well, or even not > use it at all (in some special cases.) > Thanks, I'll take a look. I also have a couple other versions of the same code which I want to post with this one. The most complex is around 30 lines to deal with posted variables. One of the nice things with using INPUT_GET was that even if PHP is configured not to create the $_GET superglobal, you can always get the original query info from it. Wheras if you configure PHP not to create the $_POST variable then you have to use the php://input stream - so it takes a few more lines for that as well as adding a set and exists option to filtering. My thinking is that it can all be crosslinked. Promote the simple 4 liners as the minimum, while providing links to more complex bits of code like this one which they can grow into: // 30ish lines to sanitize and modify query string variables // FIXME: make sure to use custom filters for your needs unset($_POST); // Force yourself not to use the global variable $post = function($varName, $filter=FILTER_SANITIZE_STRING, $action='get',$value=null) { // Internal variable to allow updating of input data static $pRaw = false; // Load the post data from input if (!is_array($pRaw)) { $postInput = file_get_contents('php://input'); echo 'post input is ' . $postInput; if ($postInput) { parse_str($postInput, $pRaw); } else { $pRaw = array(); } } $return = null; if ($action == 'get' & isset($pRaw[$varName])) { $return = filter_var($pRaw[$varName], $filter); } if($action == 'set') { if (isset($pRaw[$varName]) ) { $return = $pRaw[$varName]; } $pRaw[$varName] = $value; } if ($action =='has') { $return = isset($gRaw[$varName]); } return $return; } From chsnyder at gmail.com Wed May 21 13:14:20 2014 From: chsnyder at gmail.com (Chris Snyder) Date: Wed, 21 May 2014 13:14:20 -0400 Subject: [nycphp-talk] Promote Secure Coding In-Reply-To: <537CC1AD.50102@gmail.com> References: <537CC1AD.50102@gmail.com> Message-ID: Why use an anonymous function? That seems less readable than declaring function get( $varName ), and the explanation of anonymous functions distracts from your point, which is that you should always filter input. But yeah, quick tutorials tend to over-simplify. Writers make a lot of assumptions about readers' awareness of security issues and good coding practices. It's a fundamental problem -- PHP is easy to learn, but a security mindset is difficult to teach. Chris Snyder http://chxor.chxo.com/ On Wed, May 21, 2014 at 11:09 AM, Gary Mort wrote: > I was looking at a tutorial written in this century for PHP programming, > and I had steam come out of my ears. > > Even in this day and age, so called PHP 'experts' still write tutorials > where they create a simple hello world script which uses: > > $name = $_GET['name']; > > The concept of using the simple filter_input() function is not addressed > in almost any tutorials, and those that do address it don't bother untill > the second half of the book. > > I understand why they do this. Explaining all the intricacies of > filter_input is an advanced topic. Moreover, using $_GET and $_POST make > it very easy for instructional purposes to provide visual cues to the > student for where this data comes from. > > Never the less, since we can create closure's in PHP and bind them to > variables, it's a simple matter to use an anonymous function bound to $get > and still maintain clarity. It can even be bound to $_GET so all they need > to do is change [] to ()! > > So I wanted some feedback on the wording of the following to promote using > 4 little lines of code to reduce PHP security issues: > > ## Do not do as they doAs you learn how to program in PHP you will find almost all instructional tutorials as of 2014 do you a grave injustice. They teach you how to write dangerous, hackable, insecure PHP code. > > Since I can't wave a magic wand and make all those tutorials fix themselves, I have decided to instead provide you with a simple way to not let them do this to you. > > For any tutorial which ever tells you to get data submitted by a user by using the $_GET superglobal variable, you can perform a simple substitution: > > If they say: > $exampleVariable = $_GET['exampleVariable']; > > You should use: > $exampleVariable = $get('examplevariable); > > This is a small change that looks similar visually, so it makes it easy for you to substitute. Instead of getting the data from an array, you are getting the data using a function. > > Now in addition to the above, you will ALSO need to create this function. So at the top of any PHP file where you will be using this function, simple add the following 4 lines: > > > // FIXME: replace this with a more complete data sanitizing script > if isset($_GET) { unset($_GET); } // Force yourself not to use the global variable > $get = function($varName) { > return filter_input(INPUT_GET, $varName, FILTER_SANITIZE_STRING); } > > ## What this does > // FIXME: replace this with a more complete data sanitizing script > This is a PHP comment, it is not executable code. This is simply a notation to remind you in the future if you are using this file for a production website, to go back and replace this code with more appropriate and secure code. > > if isset($_GET) { unset($_GET); } // Force yourself not to use the global variable > This line is to force you not use the $_GET array by deleting it. That way if you cut and paste code from a tutorial, you won't accidentally introduce security issues if you forget to make the neccessary changes. > > > $get = function($varName) { > return filter_input(INPUT_GET, $varName, FILTER_SANITIZE_STRING); } > > These 2 lines create a function to remove any HTML tags from a query string variable and return it. The function is a special PHP construct called a closure, which you can learn about later, which allows it to be refereneced by a variable. The purpose of using this odd construct is that it allows you to reuse these 2 lines of code multiple times in a PHP application without having to worry about duplicate function names. > > The filter_input is a PHP function which provides a create deal more security options then just the one I have used here. It is up to you to learn about and use those options appropriately. What I have included here is the bare minimum to provide some basic security AND to allow you to easily increase your security incremementally. For example, instead of having to rewrite every single PHP program you write in the beginning, you merely need to search for all the FIXME strings and change filter_input(INPUT_GET, $varName, FILTER_SANITIZE_STRING) to something more appropriate for your specific needs. > > > > _______________________________________________ > New York PHP User Group Community Talk Mailing List > http://lists.nyphp.org/mailman/listinfo/talk > > http://www.nyphp.org/show-participation > -------------- next part -------------- An HTML attachment was scrubbed... URL: From garyamort at gmail.com Wed May 21 13:21:03 2014 From: garyamort at gmail.com (Gary Mort) Date: Wed, 21 May 2014 13:21:03 -0400 Subject: [nycphp-talk] Proper Form Processing Techniques In-Reply-To: References: <537A4211.4010105@gmail.com> Message-ID: <537CE07F.3040103@gmail.com> On 05/20/2014 04:24 AM, Michael B Allen wrote: > > I actually started out doing what you describe but I thought the > server side code started to get a little messy so I thought I would > break things up into add, remove, applyCode and so on. Right, and you can still do that. Ie you have an add function, an applyCode function, a remove function, etc. Then your update function just chains all 3 functions together. > As for other's suggestions about storing state on the client by what > is ultimately manipulating the DOM with JavaScript, I can see how that > could be used to create sophisticated UI elements. But I don't think I > would ever put any state on the client that I couldn't accept losing > at any moment (e.g. as I type this, gmail is periodically saving this > message with async requests). Even storing stuff in a cookie seems > dubious for a shopping cart. Actually, I find the best mechanism is to use a localDB data storage for almost anything where you are storing data - but that means limiting your code to browsers supporting some minimal amount of HTML5. By storing your "draft" data in a localDB, you then will have an easier time converting your code from an online app to an offline app. For example, when I use the gmail interface, I enable it's offline mode so all the draft data is saved to my local db. If I happen to be travelling on the train with internet cutting in and out, then I can still compose e-mail and it will be sent when I'm online again. Shopping carts can find this especially useful in that then you can have offline mobile apps so your customers can still spend money even when offline. :-) Or at least add to their cart. It does mean some extra work on your part though - doing that means you have to verify that the price they have in their cart matches the current price when they go to pay - and if it doesn't give them a chance to modify things. From ramons at gmx.net Wed May 21 13:22:18 2014 From: ramons at gmx.net (David Krings) Date: Wed, 21 May 2014 13:22:18 -0400 Subject: [nycphp-talk] Promote Secure Coding In-Reply-To: <537CC1AD.50102@gmail.com> References: <537CC1AD.50102@gmail.com> Message-ID: <537CE0CA.7090607@gmx.net> On 5/21/2014 11:09 AM, Gary Mort wrote: > $name = $_GET['name']; > $get = function($varName) { > return filter_input(INPUT_GET, $varName, FILTER_SANITIZE_STRING); } > > These 2 lines create a function to remove any HTML tags from a query string variable and return it. First of all, thanks for the explanation. But what would one do if the string is supposed to contain HTML tags? Just because we want to remove HTML tags from some input we might not want to remove it from all input. Also, maybe we want to employ different types of filters? Maybe the right thing in a tutorial is to first demo $name = $_GET['name']; and then explain why using input_filter is a good idea and which other filter options there are, such as first sanitizing for email and then checking for a valid email address format (that is neat!). Cleaning or filtering input is a second step. Once that concept is clear, introduce the your proposal as a means to make it impossible to forget to filter input and point out the potential drawback. I find tutorials and books intimidating that assume that everyone is stupid except the author and that one first has to go through a few dozen steps to 'fix' what the author considers totally broken. Ever read a book from Joe Celko? As much as he is an SQL guru he is a lousy author. Does the filter rip out anything that looks like a tag or does it actually compare against a list? So would a potentially harmless get taken out as well? Explaining that all will take a few pages and examples and the tutorial user probably lost interest already. Knowing better I'd appreciate that excourse, because it is better that way than any of these Java tutorials that tell you to use public static final String DEPARTMENT = "Development "; and fail to explain what public, static, and final actually do and why you'd want to use it and why it is different within a method and outside a method. For that reason I tossed a good number of Java tutorials in the digital ash can. I get your point and found it very informatibe because I didn't come across this way back when I did more with PHP. Most likely because it was not covered in the tutorials and books that I used. - David From garyamort at gmail.com Wed May 21 13:30:05 2014 From: garyamort at gmail.com (Gary Mort) Date: Wed, 21 May 2014 13:30:05 -0400 Subject: [nycphp-talk] Promote Secure Coding In-Reply-To: References: <537CC1AD.50102@gmail.com> Message-ID: <537CE29D.9030301@gmail.com> On 05/21/2014 01:14 PM, Chris Snyder wrote: > Why use an anonymous function? That seems less readable than declaring > function get( $varName ), and the explanation of anonymous functions > distracts from your point, which is that you should always filter input. To make it cut and pasteable without any thought. File A: $get = function($varName) {}; ....lots of code in a file.... File B: $get = function($varName) {}; include('filea.php'); Unbroken, usable code despite re-declaration. A little bit of extra memory will be used, but thats a small price to pay. File A: function get($varName) {}; ....lots of code in a file.... File B: function get($varName) {}; include('filea.php'); ^^^^breaks because the function get is already declared Also, quite honestly the point of documenting it is not to inform the new programmer. The point is that if this is posted to the internet somewhere[I submitted a first draft to www.phptherightway.com for example] Then in articles on programming in PHP, instead of saying: $myVar = $_GET['myvar']; The author can instead say: "Include these 4 lines at the top of your file for security. If you want to learn about it see ..." And then they can write $myVar = $get('myvar'); And any author or book written in 2015 or later which uses the super globals in example code can be justly ridiculed on the internet. :-) From garyamort at gmail.com Wed May 21 13:43:30 2014 From: garyamort at gmail.com (Gary Mort) Date: Wed, 21 May 2014 13:43:30 -0400 Subject: [nycphp-talk] Promote Secure Coding In-Reply-To: <537CE0CA.7090607@gmx.net> References: <537CC1AD.50102@gmail.com> <537CE0CA.7090607@gmx.net> Message-ID: <537CE5C2.6060001@gmail.com> On 05/21/2014 01:22 PM, David Krings wrote: > On 5/21/2014 11:09 AM, Gary Mort wrote: >> $name = $_GET['name']; >> $get = function($varName) { >> return filter_input(INPUT_GET, $varName, FILTER_SANITIZE_STRING); } >> >> These 2 lines create a function to remove any HTML tags from a query >> string variable and return it. > > First of all, thanks for the explanation. But what would one do if the > string is supposed to contain HTML tags? Just because we want to > remove HTML tags from some input we might not want to remove it from > all input. Also, maybe we want to employ different types of filters? My target is a simple cut and paste for tutorials and teaching PHP - where FILTER_SANITIZE_STRING is sufficient for most use cases[ie echo "Hello $name" where $name comes from a query variable]. Personally, I don't think tutorials should EVER use super global variables. They should instead have written: $name = *filter_input(INPUT_GET, 'name', FILTER_SANITIZE_STRING); * However, there are lots of books already written, and lots of people who are simply cut and pasting from those books and tutorials and then modifying to suite their need. So my goal is a simple "before you being, always use this instead of $_GET". I think it would probably be best to make sure the explanation is actually on a seperate page...ie most new programmers don't know or care how PHP creates the $_GET supervariable - so their just as unlikely to care about why I'm using closures or how filter_input works. Instead they can simply use $get as a 'magic function' to make their code more secure. I resisted mightily the desire to expound on why I used FIXME - it's a commonly used string tag which all programming IDE's will automatically provide a list of all FIXME notes in the code[PHPStorm for example defaults to prompting me if I try to commit code to git with TODO and FIXME notes in it]. > > Maybe the right thing in a tutorial is to first demo $name = > $_GET['name']; and then explain why using input_filter is a good idea > and which other filter options there are, such as first sanitizing for > email and then checking for a valid email address format (that is > neat!). Cleaning or filtering input is a second step. Yes, I agree. A tutorial should always go into filtering input at the same time it introduces retrieiving input. What sparked my code here though was discovering that Zend published a long, detailed PHP101 article this year....and they don't bother to discuss filtering input until long after retrieiving input and placing it into a database. So for the lazy writer who doesn't want to go into it, they can give their readers 4 lines of code to make things a little better. -------------- next part -------------- An HTML attachment was scrubbed... URL: From ircmaxell at gmail.com Wed May 21 14:32:31 2014 From: ircmaxell at gmail.com (Anthony Ferrara) Date: Wed, 21 May 2014 14:32:31 -0400 Subject: [nycphp-talk] Promote Secure Coding In-Reply-To: <537CE5C2.6060001@gmail.com> References: <537CC1AD.50102@gmail.com> <537CE0CA.7090607@gmx.net> <537CE5C2.6060001@gmail.com> Message-ID: First off, I do $name = $_GET['name']. I filter when I know what's going to happen with it (such as when it gets bound against a data model). Filter_input is literally the wrong tool for the job. Around 95% of the time at least. It's a horrific API. It's not secure. It's broken. It lies to you. Example: you're using filter_var with FILTER_SANITIZE_STRING. Do you know what that *really* means under the hood? It's really no better than running strip_tags. And we know that we shouldn't be running strip_tags, right? Instead, we need to FILTER IN, ESCAPE OUT. Filter input, means **validating**. Not "sanitizing". And there's no generic way to validate arbitrary data. It requires understanding of what you're trying to do. It requires understanding of the data model. And that's why a solution like you're proposing is bad. It conflates filtering with escaping. And that's **always** a bad thing. Input should be verified (that it adheres to the data domain). Output should be encoded (or escaped) **at the point of output**, specifically for the method of output being used. You wouldn't DB escape when you output to a webpage, so why are you html escaping when you output to the database? Give this post a read: http://blog.ircmaxell.com/2011/03/what-is-security-web-application.html And instead of using filter_var, I'd suggest a library that doesn't conflate filtering with escaping. Something like (I know I am biased): https://github.com/ircmaxell/filterus Anthony On Wed, May 21, 2014 at 1:43 PM, Gary Mort wrote: > > On 05/21/2014 01:22 PM, David Krings wrote: > > On 5/21/2014 11:09 AM, Gary Mort wrote: > > $name = $_GET['name']; > $get = function($varName) { > return filter_input(INPUT_GET, $varName, FILTER_SANITIZE_STRING); } > > These 2 lines create a function to remove any HTML tags from a query string > variable and return it. > > > First of all, thanks for the explanation. But what would one do if the > string is supposed to contain HTML tags? Just because we want to remove HTML > tags from some input we might not want to remove it from all input. Also, > maybe we want to employ different types of filters? > > > My target is a simple cut and paste for tutorials and teaching PHP - where > FILTER_SANITIZE_STRING is sufficient for most use cases[ie echo "Hello > $name" where $name comes from a query variable]. > > Personally, I don't think tutorials should EVER use super global variables. > They should instead have written: > $name = filter_input(INPUT_GET, 'name', FILTER_SANITIZE_STRING); > > However, there are lots of books already written, and lots of people who are > simply cut and pasting from those books and tutorials and then modifying to > suite their need. > > So my goal is a simple "before you being, always use this instead of $_GET". > I think it would probably be best to make sure the explanation is actually > on a seperate page...ie most new programmers don't know or care how PHP > creates the $_GET supervariable - so their just as unlikely to care about > why I'm using closures or how filter_input works. Instead they can simply > use $get as a 'magic function' to make their code more secure. > > I resisted mightily the desire to expound on why I used FIXME - it's a > commonly used string tag which all programming IDE's will automatically > provide a list of all FIXME notes in the code[PHPStorm for example defaults > to prompting me if I try to commit code to git with TODO and FIXME notes in > it]. > > > Maybe the right thing in a tutorial is to first demo $name = $_GET['name']; > and then explain why using input_filter is a good idea and which other > filter options there are, such as first sanitizing for email and then > checking for a valid email address format (that is neat!). Cleaning or > filtering input is a second step. > > > Yes, I agree. A tutorial should always go into filtering input at the same > time it introduces retrieiving input. What sparked my code here though was > discovering that Zend published a long, detailed PHP101 article this > year....and they don't bother to discuss filtering input until long after > retrieiving input and placing it into a database. > > So for the lazy writer who doesn't want to go into it, they can give their > readers 4 lines of code to make things a little better. > > _______________________________________________ > New York PHP User Group Community Talk Mailing List > http://lists.nyphp.org/mailman/listinfo/talk > > http://www.nyphp.org/show-participation From greg at freephile.com Thu May 22 09:49:49 2014 From: greg at freephile.com (Greg Rundlett (freephile)) Date: Thu, 22 May 2014 09:49:49 -0400 Subject: [nycphp-talk] Proper Form Processing Techniques In-Reply-To: References: Message-ID: On Sun, May 18, 2014 at 1:43 AM, Michael B Allen wrote: > Hi All, > > Occasionally I need to do a little web programming and I must admit > after almost 2 decades I still find myself searching for a better way > to handle HTML forms. I blame this mostly on the W3C's invalid > assumption that HTML is for rendering documents and not building > applications. But putting blame aside, I would like to ask the list to > share their best form processing techniques. > > Use Node.js. This O'Reilly article from 2011 http://radar.oreilly.com/2011/07/what-is-node.html introduces node.js in a pretty general way. Node.js isn't the answer to everything, and since it's not directly related to form processing one might think it doesn't answer OP's question. But it is a great development that has happened over the past n<20 years that does add another tool to the toolbox for solving web application needs. The other thing is to use HTML5, which among other things offers new form controls like sliders and date pickers (http://diveintohtml5.info/forms.html). Data-centric applications can benefit from a node.js implementation in tandem with web sockets can make that data available to all clients in a real-time scenario. Greg Rundlett http://eQuality-Tech.com http://freephile.org -------------- next part -------------- An HTML attachment was scrubbed... URL: From garyamort at gmail.com Thu May 22 10:26:29 2014 From: garyamort at gmail.com (Gary Mort) Date: Thu, 22 May 2014 10:26:29 -0400 Subject: [nycphp-talk] Promote Secure Coding In-Reply-To: References: <537CC1AD.50102@gmail.com> <537CE0CA.7090607@gmx.net> <537CE5C2.6060001@gmail.com> Message-ID: <537E0915.5070905@gmail.com> On 05/21/2014 02:32 PM, Anthony Ferrara wrote: > First off, I do $name = $_GET['name']. I filter when I know what's > going to happen with it (such as when it gets bound against a data > model). But your not a novice programmer, so this doesn't apply to you. Though personally, I wouldn't do $name = $_GET['name']. I'd use $name = filter_input(INPUT_GET, 'name', FILTER_UNSAFE_RAW) $_GET is fine when you are writing code for a specific platform where you know in advance what the configuration will be. However, I'm seeing a lot of linux distro's have started set filter_default to FILTER_SANITIZE_STRING in their PHP install packages. I prefer writing code which doesn't depend on specific php.ini directives in order to work. > > > Example: you're using filter_var with FILTER_SANITIZE_STRING. Do you > know what that *really* means under the hood? > > It's really no better than running strip_tags. And we know that we > shouldn't be running strip_tags, right? For this use case, yes we should. Consider the secretary updating their company website. They have been told that they need some landing page to say "Welcome " at the top. The pages are mostly html with a bit of PHP here and there. So they go to an online tutorial, go through steps 1-4 where they learn about "hello world" which is a simple little tutorial of $name = $_GET['name']; echo "Hello $name"; Well, that's good enough for their needs. A small tweak and now they have the page and the company sends out e-mail to their clients and all they have to do is add ?name=XXX on the e-mail. They ALSO have a horrible cross site scripting issue where someone else can craft custom links to their website and insert any html and javascript they want to. Strip tags is the correct solution for 90% of introductory coding. It sanitizes the input from a bunch of common exploits. On the downside, it removes all text from within angle brackets - but 95% of all minor uses of PHP it means everything just works. > > And that's why a solution like you're proposing is bad. It conflates > filtering with escaping. And that's **always** a bad thing. Nope, all solutions are based on what is simplest, what performs best, what is most comprehensive, and what is most appropriate. My solution maximizes simplest - because that is the most important thing for beginning programmers. And deals with what is most appropriate for new programmers. When people are learning, they put the code up on whatever 'temporary' web space they have at hand. Whether that is a godaddy site they just setup, a subdirectory on an active website someone has given them, on virtual systems running as subdomains for a university vps123.sandbox.marist.edu [which means that they can set cookie information for the entire marist.edu domain] And when their done, they forget about it and leave it running - publicly accessible and exploitable. That harms everyone on the internet - because those exploitable bits of code are used as launching points for denial of service attacks, controlling e-mail spam botnets, and many more. Furthermore, unlike most solutions out there, using an anonmous function tied to a variable means that as programmer learns, they can grow and make it better. Eventually, they will get to the point where they learn about including files and maintaining common code. So then, instead of sticking 4 lines of code at the top of every php file, they can move it all to a file of common declarations. Then they will learn about better ways of filtering data, so instead of going through every piece of legacy code that they have, they can instead change it in one place. $get = function($varName, $filter = 'string') { $var = filter_input(INPUT_GET, $varName, FILTER_UNSAFE_RAW); return \Filterus\filter($var, $filter); } If instead they started with using a specific filter library and then discover that the library is no longer supported, then they have to go throughout ALL their code where they called $var = \Filterus\filter($var, $filter); And change every single instance.... of course, this assumes that they had the patience to wait until they reached the course section on filtering data. And for the professional PHP developers, promoting these simple 4 lines has an added benefit. When the small business grows and reaches the point of needing to hire a professional - when the professional opens that code up in their IDE they can easily find every instance of problem code - since it is all flagged with the \\FIXME: tag which every IDE I know of automatically will parse and display a list of ever single instance of those tags[in PHPStorm it's View-->Tools-->ToDo] I'm certainly open to alternatives that actually address the problem: novice programmers writing insecure code. https://github.com/ircmaxell/filterus as it is written right now is not it. Looking at that page, you have to go all the way to the bottom to get something a novice programmer might be able to use - and even there what is written is not of any real use. But then, I assume that you didn't write it for the novice programmer, so I don't see a problem with it. Just re-iterating that it doesn't address the same issues my solution does. From garyamort at gmail.com Thu May 22 10:49:22 2014 From: garyamort at gmail.com (Gary Mort) Date: Thu, 22 May 2014 10:49:22 -0400 Subject: [nycphp-talk] PHP is not just for professionals Message-ID: <537E0E72.9010203@gmail.com> Anthony's comments on my last post reminded me of an issue I feel PHP is facing today. PHP is a wonderfully messy language. You can use PHP to insert a small bit of customization in an otherwise flat website. Something as simple as saying "Good morning", "Good afternoon", and "Good evening" at the top of a welcome page. Adding a small hit counter. This usage allows for everyone to customize their own websites - which is one of the great strengths of the open source community - the idea that we empower the end users to do whatever they want for themselves. It allows for a gentle learning curve, where you can go from little bits of PHP to a complex set of conditions and actions on a single PHP page, and then on to seperating code out into libraries of common functions but still single pages, and finally to frameworks and obtuse programs such as ===== execute(); ====== Maybe it is just me, but I see more and more a focus on obtuse programming. It is seen as "professional" and "secure"....and incidentally programmers can charge a lot more money when the programs are so complex that the end user can't make their own modifications anymore. When I first started out with PHP over 20 years ago, I found it to be an open community of people passing on hints and help - very open with their help and supportive of new coders. Contrasting that with Python and Rails, I found them to be greedy communities, where everyone is a "professional" and "available for consultation". Now....I'm not so sure. It seems to me that PHP is becoming more "professional". Am I alone in this? From ircmaxell at gmail.com Thu May 22 11:35:39 2014 From: ircmaxell at gmail.com (Anthony Ferrara) Date: Thu, 22 May 2014 11:35:39 -0400 Subject: [nycphp-talk] Promote Secure Coding In-Reply-To: <537E0915.5070905@gmail.com> References: <537CC1AD.50102@gmail.com> <537CE0CA.7090607@gmx.net> <537CE5C2.6060001@gmail.com> <537E0915.5070905@gmail.com> Message-ID: Gary, On Thu, May 22, 2014 at 10:26 AM, Gary Mort wrote: > On 05/21/2014 02:32 PM, Anthony Ferrara wrote: >> First off, I do $name = $_GET['name']. I filter when I know what's >> going to happen with it (such as when it gets bound against a data >> model). > But your not a novice programmer, so this doesn't apply to you. Though > personally, I wouldn't do $name = $_GET['name']. I'd use $name = > filter_input(INPUT_GET, 'name', FILTER_UNSAFE_RAW) Then you completely missed the point of what my intention was. And why in the world would you use FILTER_UNSAFE_RAW over $_GET['name']? There is quite literally no benefit. And you're running it through a method for literally no reason. Exposing yourself to potential bugs in the process. Aim for readability, use input directly. > $_GET is fine when you are writing code for a specific platform where you > know in advance what the configuration will be. > > However, I'm seeing a lot of linux distro's have started set filter_default > to FILTER_SANITIZE_STRING in their PHP install packages. And that's a horrific idea. And one reason you should avoid the filter_* APIs at all costs. > I prefer writing code which doesn't depend on specific php.ini directives in > order to work. That has nothing to do with what we're talking about. I'm talking about using request information directly. If you're using a framework, use its request object. If you're not, use the superglobals directly. But please don't use filter_*. You think you're making yourself safer. It tells you it's safer, but it's not. In many cases, it's worse. > >> >> >> Example: you're using filter_var with FILTER_SANITIZE_STRING. Do you >> know what that *really* means under the hood? >> >> It's really no better than running strip_tags. And we know that we >> shouldn't be running strip_tags, right? > > > For this use case, yes we should. Absolutely not. strip_tags is known to be unsafe. It's not something you should rely upon for security. And that's what we're talking about here. > Consider the secretary updating their company website. They have been told > that they need some landing page to say "Welcome " at the top. > > The pages are mostly html with a bit of PHP here and there. So they go to > an online tutorial, go through steps 1-4 where they learn about "hello > world" which is a simple little tutorial of > $name = $_GET['name']; > echo "Hello $name"; Who said to `echo "Hello $name"`? I sure didn't. I said you need to escape and encode properly for the output context. If you're rendering to HTML, as a property or as a text node, you **must** use htmlspecialchars. And you **must** use it properly: echo "Hello " . htmlspecialchars($name, ENT_QUOTES | ENT_DISALLOWED | ENT_HTML5, "utf-8"); Anything else is likely going to have holes in it that would allows you to possibly exploit certain circumstances (just like strip_tags does). Yes, that's a lot to write, but more on that in a minute. > Well, that's good enough for their needs. A small tweak and now they have > the page and the company sends out e-mail to their clients and all they have > to do is add ?name=XXX on the e-mail. > > They ALSO have a horrible cross site scripting issue where someone else can > craft custom links to their website and insert any html and javascript they > want to. Which is why you never output unescaped data. But the point is that you escape it **on output**. NOT on input. > Strip tags is the correct solution for 90% of introductory coding. It > sanitizes the input from a bunch of common exploits. On the downside, it > removes all text from within angle brackets - but 95% of all minor uses of > PHP it means everything just works. It absolutely is not. It's very well understood that it's not ideal: Example: http://stackoverflow.com/questions/3605629/php-prevent-xss-with-strip-tags Example: https://isisblogs.poly.edu/2013/07/02/php-strip_tags-not-a-complete-protection-against-xss-repost-from-archive/ Example: http://security.stackexchange.com/questions/10011/is-strip-tags-horribly-unsafe Example: http://forums.devshed.com/php-development-5/strip_tags-removes-html-tags-stop-xss-934238.html Instead, you should follow actual recommendations on the subject: https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet > > >> >> And that's why a solution like you're proposing is bad. It conflates >> filtering with escaping. And that's **always** a bad thing. > > Nope, all solutions are based on what is simplest, what performs best, what > is most comprehensive, and what is most appropriate. And what you're recommending is neither simplest, best, most comprehensive or appropriate. > My solution maximizes simplest - because that is the most important thing > for beginning programmers. And deals with what is most appropriate for new > programmers. There are easier solutions that that. But more on that in a second. > When people are learning, they put the code up on whatever 'temporary' web > space they have at hand. Whether that is a godaddy site they just setup, a > subdirectory on an active website someone has given them, on virtual systems > running as subdomains for a university vps123.sandbox.marist.edu [which > means that they can set cookie information for the entire marist.edu domain] > > And when their done, they forget about it and leave it running - publicly > accessible and exploitable. > > That harms everyone on the internet - because those exploitable bits of code > are used as launching points for denial of service attacks, controlling > e-mail spam botnets, and many more. > > Furthermore, unlike most solutions out there, using an anonmous function > tied to a variable means that as programmer learns, they can grow and make > it better. > > Eventually, they will get to the point where they learn about including > files and maintaining common code. So then, instead of sticking 4 lines of > code at the top of every php file, they can move it all to a file of common > declarations. > > Then they will learn about better ways of filtering data, so instead of > going through every piece of legacy code that they have, they can instead > change it in one place. > > $get = function($varName, $filter = 'string') { > > $var = filter_input(INPUT_GET, $varName, FILTER_UNSAFE_RAW); > return \Filterus\filter($var, $filter); > } PLEASE NO. This kind of thinking that security is "generic" and something you can just sprinkle on after the fact and tune is part of the reason XSS is so prevalant. Because you have people writing functions like make_safe($name) { return mysql_real_escape_string(addslashes(htmlspecialchars($_REQUEST[$name]))); } And I strongly hope I don't need to elaborate on why that's a horrific idea. > If instead they started with using a specific filter library and then > discover that the library is no longer supported, then they have to go > throughout ALL their code where they called > $var = \Filterus\filter($var, $filter); Which if you used abstraction, isn't that many places. But more on that in a minute. > And change every single instance.... of course, this assumes that they had > the patience to wait until they reached the course section on filtering > data. > > And for the professional PHP developers, promoting these simple 4 lines has > an added benefit. When the small business grows and reaches the point of > needing to hire a professional - when the professional opens that code up in > their IDE they can easily find every instance of problem code - since it is > all flagged with the \\FIXME: tag which every IDE I know of automatically > will parse and display a list of ever single instance of those tags[in > PHPStorm it's View-->Tools-->ToDo] > > I'm certainly open to alternatives that actually address the problem: novice > programmers writing insecure code. https://github.com/ircmaxell/filterus as > it is written right now is not it. Looking at that page, you have to go all > the way to the bottom to get something a novice programmer might be able to > use - and even there what is written is not of any real use. But then, I > assume that you didn't write it for the novice programmer, so I don't see a > problem with it. Just re-iterating that it doesn't address the same issues > my solution does. The point is that there's a difference between input and output. You **never** escape input. That's the wrong place to do it. It leads to second-order injections and XSS. Where you thought the data in the database was safe, because you escaped it when it came in the first time. But that doesn't mean it will be safe forever. Example: what if your escaping routine isn't good enough, and there's a bug. Now you're screwed. Because you need to change it, but all of your data is already escaped. So instead, you're stuck having to either double-encode everything (yuck), or somehow go back and re-parse everything in the DB to fix it. Both solution SUCK. And I've done both of them in the past. And it sucked. And you should be doing that right now, since you're not safe either (as I pointed out, filter_var doesn't actually protect you from XSS). The correct way of handling these issues is splitting up filtering (ensuring input is in a valid data domain) and escaping (ensuring output is encoded properly for the output context). For input, Filterus, or even is_string, etc can help a lot. The point though is that you want to verify that the data is valid to you. Not that it's safe from XSS. That it's valid for your business purpose. That's all you should **ever** worry about from input. For output, the easiest, simplest and most proper way to handle this sort of thing is by not handling it at all. Use a templating engine like Twig or Mustache, which will auto-escape for you by default. This isn't a magic bullet, as output into JS or CSS contexts can still cause you a lot of pain, but it handles the 98% case quite well. If you're outputting directly from PHP, either define an escape function which wraps htmlspecialchars, or don't output directly from PHP. As far as "catering to the novices", that's a completely bullshit phrasing. Novices don't need to be catered to. They don't need things to be dummbed down. They don't need to be spoon fed. They need to be educated. And telling them that "just use this and you're fine" is dangerous. And it's doubly dangerous when what you're suggesting is not actually fine (as I've pointed out numerous times in this thread. Never mediate, always educate. If you think filterus is too hard for a novice to navigate, then improve the documentation. Make a pull request to make it simpler to understand. Write a blog post explaining how to properly work these systems. Don't just assume that just because they are a beginner that they are too dumb to understand. Most of the time it's simply that they don't understand the terminology. But if you explain it to them properly, no problem. But saying that they should do the wrong thing, which is known to be insecure, because they won't be able to understand the wright thing, is horrible. Anthony From rainelemental at gmail.com Thu May 22 13:08:50 2014 From: rainelemental at gmail.com (Federico Ulfo) Date: Thu, 22 May 2014 13:08:50 -0400 Subject: [nycphp-talk] Logging best practices, 2 of 2 In-Reply-To: <536C058D.50001@gmail.com> References: <536C058D.50001@gmail.com> Message-ID: > > If you want to use a system like monolog, you can still do that while > using the user_error function, simply use the set_error_handler function > and you can route the error message to whatever flavor of the month logging > class is popular. that's a nice option, but we decided to use a wrapper to be consistent cross language and to make the code easier to maintain, as you mentioned before, is easier to change Monolog with Schmancy\Fancy inside one wrapper than everywhere into the code. I prefer syslog to all other logging transports. yup, we decided to use syslog! Truthfully, I prefer rsyslog, not syslog - but from the PHP side they are > the same thing. at our scale rsyslog could hammer our network. We log so much that we've to move the logs every night into a remote backup. For our centralized logging we use Scribe. We use it to log only specific user input such as API call, because it generate a lot of traffic inside our network, and that's why I don't think we can simply replace rsyslog with syslog, unless there's an option to store the log locally and then upload them in batch. I'll investigate if such option exists! Thanks, Federico On Thu, May 8, 2014 at 6:30 PM, Gary Mort wrote: > > On 05/06/2014 09:39 AM, Federico Ulfo wrote: > >> We're considering to use syslog as common logging for all languages, >> mostly PHP, Java and Python (Scala, Perl, Ruby ...), so we can finally log >> with a standard format, e.g.: >> TIME - HOSTNAME PID [LOG LEVEL] MESSAGE >> >> >> > I prefer syslog to all other logging transports. Using syslog means you > can save logs offsite[which is important if you ever need to do forensic > security analysis. If all the log data is on the server and the server is > compromised, the log data is compromised. Even if you archive it off, it > can still be modified before that archive occurs]. > > Truthfully, I prefer rsyslog, not syslog - but from the PHP side they are > the same thing. You can easily setup a Log Analyzer server to send all > the data to, which provides you with the ability to tail/view your logs as > your developing. And since Log Analyzer is written in PHP, you can change > it to suite your purposes. http://loganalyzer.adiscon.com/ and > http://www.rsyslog.com/ > > A common mistake I see in people implementing syslog logging is that they > use direct connections to their syslog server. IE using monolog's > StslogUdpHandler: https://github.com/Seldaek/monolog/blob/master/src/ > Monolog/Handler/SyslogUdpHandler.php > > To me, the whole point of using syslog/rsyslog is that it is FAST. Your > app connects to a syslog server over a local socket and fires strings at it. > > If you connect to a /remote/ syslog server then every single message you > log will slow down your app. I've seen some weird UDP implementations that > wait for some form of ack from the network device that the message has been > queued. Or if it is important to you, it's possible to use tcp to provide > guaranteed delivery. > > It does take a bit more configuration, but with a local rsyslog server you > can setup extremely simple 'forward every message to the remote server AND > log it locally' to complex conditional logs. > > I like to set it up to log to local files in a tmpfs directory, and then > purge the logs every couple of hours. That gives me local access to the > logs for development/debugging - while I have the remote server for > archives. Putting it on a tmpfs drive means that they get stored in > memory instead of on the hard drive so there is no issue of slowing down > the server by making it write log messages to a hard drive. > > Note: just because your using syslog does not mean you are locked into the > limitation of message being a single string. You can json_encode anything > into a string - rsyslog has a number of plugins to explode that data into > fields and then save them into a database or such. Or if you don't want > to roll your own, Papertrail provides access via the syslog protocol and > already handles json. https://papertrailapp.com/ Sometimes it's better > to just pay someone else 20-40$ a month and let them deal with the > headaches. > > And with syslog, your not locked into a vendor. You could send your log > files to papertrail, save them onto a local tmpfs drive, AND send them to a > centralized garbage heap syslog server filled with cheap drives and no real > reporting/access policy. IE keep a copy of the data archived forever > 'just in case' but don't bother setting up an interface for it until the > expense of paying a provider like papertrail grows large enough to justify > bringing it in house. > > _______________________________________________ > New York PHP User Group Community Talk Mailing List > http://lists.nyphp.org/mailman/listinfo/talk > > http://www.nyphp.org/show-participation > -------------- next part -------------- An HTML attachment was scrubbed... URL: From leamhall at gmail.com Thu May 22 14:11:51 2014 From: leamhall at gmail.com (leam hall) Date: Thu, 22 May 2014 14:11:51 -0400 Subject: [nycphp-talk] PHP is not just for professionals In-Reply-To: <537E0E72.9010203@gmail.com> References: <537E0E72.9010203@gmail.com> Message-ID: Gary, I'd have to agree with you on this. We can be happy that PHP is now a professional grade enterprise capable solution. However, frameworks, "modern" coding practices, and a host of other things make it very difficult for someone to climb the learning curve. That may be just my perception. Leam On Thu, May 22, 2014 at 10:49 AM, Gary Mort wrote: > Anthony's comments on my last post reminded me of an issue I feel PHP is > facing today. > > ===== > > $app = Factory::getApplication(); > $app->execute(); > ====== > -- Mind on a Mission -------------- next part -------------- An HTML attachment was scrubbed... URL: From garyamort at gmail.com Thu May 22 16:21:02 2014 From: garyamort at gmail.com (Gary Mort) Date: Thu, 22 May 2014 16:21:02 -0400 Subject: [nycphp-talk] Promote Secure Coding In-Reply-To: References: <537CC1AD.50102@gmail.com> <537CE0CA.7090607@gmx.net> <537CE5C2.6060001@gmail.com> <537E0915.5070905@gmail.com> Message-ID: <537E5C2E.3020908@gmail.com> On 05/22/2014 11:35 AM, Anthony Ferrara wrote: > Gary, > >> Consider the secretary updating their company website. They have been told >> that they need some landing page to say "Welcome " at the top. >> >> The pages are mostly html with a bit of PHP here and there. So they go to >> an online tutorial, go through steps 1-4 where they learn about "hello >> world" which is a simple little tutorial of >> $name = $_GET['name']; >> echo "Hello $name"; > Who said to `echo "Hello $name"`? I sure didn't. That was stated in my original post. I thought I was quite clear that this method was for a specific class of users and I gave the example. This is the common instructional pattern for teaching others PHP. They almost all start with "Hello World" and follow it with "Hello $name" where $name directly from $_GET['name'] That's why I made an effort to avoid using the pronoun "you" when discussing using this method. IE I did not say "you" should use this method meaning Anthony... nor did I say "you" to refer suggesting people on this e-mail list should use this method. The only time I deliberately use the word "you" is in the actual text of my proposed "before you begin learning PHP programming" because there the pronoun you refers directly to the individual who doesn't know PHP at all yet. Not bothering to address the rest of your comments since they seem to be based on a misunderstanding. From garyamort at gmail.com Thu May 22 16:44:23 2014 From: garyamort at gmail.com (Gary Mort) Date: Thu, 22 May 2014 16:44:23 -0400 Subject: [nycphp-talk] filter_input misconceptions Message-ID: <537E61A7.2030600@gmail.com> It seems there are some misconceptions on the filter_* API. Recently I was contacted by a colleague when his website went off kilter. All of the sudden all the variables had extra html encoding charectors in them....and then since they were encoded a second time when displayed they would have even more. This was on a server I had worked on a few months previously and this was not happening. So I took a look at the configuration and discovered that filter_default had been changed. It turned out that PHP on the server had recently been upgraded from the CentOS repositories and the default settings changed. http://us3.php.net/manual/en/filter.configuration.php#ini.filter.default Looking into it a bit more, I experiemented with some different options on various settings which control the creation of the super global variables, after which I decided that it is better to use $var = filter_input(INPUT_GET, 'myvar', FILTER_UNSAFE_RAW); then $_GET in the future[though of course if in a framework which provides an interface to the http variables it is better to use the framework to be consistent] Note, FILTER_UNSAFE_RAW - this is not a security decision, it is a stability decision. First off, if you use $_GET then you ALSO are using the filter_input API. All global variables are populated by passing them through filter_input. By design, the default filter will be FILTER_UNSAFE_RAW however there is no way to change this from within your PHP code. It can only be set before the execution of the PHP script[either in the php.ini file or, with apache, you can set a custom ini variable in .htaccess]. Presuming my colleague gave me the correct information on where the upgrade came from, it seems that the latest CentOS PHP packages instead use FILTER_SANITIZE_FULL_SPECIAL_CHARS Since you[and by you I mean anyone publishing PHP code where they can't control the server configuration it will be executed on] can't get away from it being used, the best you can do is force it to do exactly what you want. IE if you want raw data, use filter_input and FILTER_UNSAFE_RAW so you make sure to get what you expect to get, and not something set by the server. In addition, the global variables $_GET, $_SERVER, $_ENV, $_SESSION, $_COOKIE, $_REQUEST, and $_POST simply can't be trusted. Only filter_input will give you access to the true data for 4 out of those 7 variables. It does not give you access to $_SESSION and while it does give you access to INPUT_POST but there are a couple edge cases where it will not provide the post data. The php.ini settings filter.default, track-vars, and variables-order can all change what is stored in the super globals. http://us3.php.net/manual/en/filter.configuration.php#ini.filter.default http://us3.php.net/manual/en/ini.core.php#ini.track-vars http://us3.php.net/manual/en/ini.core.php#ini.variables-order Without doing detailed checking of the various combinations from inside the code, there is no way to tell which of those variables actually has data and what filtering has already been done to them. In addition, $_SERVER may or may not include both $_SERVER and $_ENV variables[running google app engine's dev server they will be combined, when you are on the actual production server they are not] With auto-globals-jit the $_SERVER and $_ENV variables may or may not even be available. http://us3.php.net/manual/en/ini.core.php#ini.auto-globals-jit Thanks to request-order, the order of variables in $_REQUEST can be anything - so if I want a specific combination of possibilities, I retrieve that combination rather then hope that request-order was not changed from the default 'GPC' http://us3.php.net/manual/en/ini.core.php#ini.request-order $_POST is an even more interesting. If you disable $_POST - either by setting variable_order to 'EGCS' to exclude posted data then filter_input will not return any data for posted variables. auto_glabls_jit provides an even odder edge case. With just in time creation enables, $_POST will not be created when PHP is running unless you try to access something from the array. This also affects whatever internal structure filter_input() uses and filter_input() does not trigger the creation of post variables. So if you call filter_input() after calling something like isset($_POST['anynonexistantvariable'] it works. If you call it before it does not. To safely deal with post you need to parse the post data from php://input .. and for php://input is inconsistent in that depending on compile options it may be possible to read it multiple times, or it may be deleted after being read. From ircmaxell at gmail.com Thu May 22 17:02:52 2014 From: ircmaxell at gmail.com (Anthony Ferrara) Date: Thu, 22 May 2014 17:02:52 -0400 Subject: [nycphp-talk] filter_input misconceptions In-Reply-To: <537E61A7.2030600@gmail.com> References: <537E61A7.2030600@gmail.com> Message-ID: Gary, I just checked CentOS 6.5's RPM, and it has filter.default set to raw (the default). So I'm not sure where you're getting "it seems that the latest CentOS PHP packages instead use FILTER_SANITIZE_FULL_SPECIAL_CHARS". There may be a distro or repo that does that, but it's not CentOS... We learned **years** ago that this doesn't work. Magic_quotes was removed because of that. Register_globals was removed. ETC. The short of it, working around that setting is not going to work. Many people tried working around magic_quotes. Fail. The only actual solution is to set it to not do anything. Anthony On Thu, May 22, 2014 at 4:44 PM, Gary Mort wrote: > It seems there are some misconceptions on the filter_* API. Recently I was > contacted by a colleague when his website went off kilter. All of the > sudden all the variables had extra html encoding charectors in them....and > then since they were encoded a second time when displayed they would have > even more. > > This was on a server I had worked on a few months previously and this was > not happening. So I took a look at the configuration and discovered that > filter_default had been changed. It turned out that PHP on the server had > recently been upgraded from the CentOS repositories and the default settings > changed. > http://us3.php.net/manual/en/filter.configuration.php#ini.filter.default > > Looking into it a bit more, I experiemented with some different options on > various settings which control the creation of the super global variables, > after which I decided that it is better to use $var > = filter_input(INPUT_GET, 'myvar', FILTER_UNSAFE_RAW); then $_GET in the > future[though of course if in a framework which provides an interface to the > http variables it is better to use the framework to be consistent] > Note, FILTER_UNSAFE_RAW - this is not a security decision, it is a stability > decision. > > First off, if you use $_GET then you ALSO are using the filter_input API. > All global variables are populated by passing them through filter_input. By > design, the default filter will be FILTER_UNSAFE_RAW however there is no way > to change this from within your PHP code. It can only be set before the > execution of the PHP script[either in the php.ini file or, with apache, you > can set a custom ini variable in .htaccess]. > > Presuming my colleague gave me the correct information on where the upgrade > came from, it seems that the latest CentOS PHP packages instead use > FILTER_SANITIZE_FULL_SPECIAL_CHARS > > Since you[and by you I mean anyone publishing PHP code where they can't > control the server configuration it will be executed on] can't get away from > it being used, the best you can do is force it to do exactly what you want. > IE if you want raw data, use filter_input and FILTER_UNSAFE_RAW so you make > sure to get what you expect to get, and not something set by the server. > > In addition, the global variables $_GET, $_SERVER, $_ENV, $_SESSION, > $_COOKIE, $_REQUEST, and $_POST simply can't be trusted. Only filter_input > will give you access to the true data for 4 out of those 7 variables. It > does not give you access to $_SESSION and while it does give you access to > INPUT_POST but there are a couple edge cases where it will not provide the > post data. > > The php.ini settings filter.default, track-vars, and variables-order can all > change what is stored in the super globals. > http://us3.php.net/manual/en/filter.configuration.php#ini.filter.default > http://us3.php.net/manual/en/ini.core.php#ini.track-vars > http://us3.php.net/manual/en/ini.core.php#ini.variables-order > > Without doing detailed checking of the various combinations from inside the > code, there is no way to tell which of those variables actually has data and > what filtering has already been done to them. In addition, $_SERVER may or > may not include both $_SERVER and $_ENV variables[running google app > engine's dev server they will be combined, when you are on the actual > production server they are not] > > With auto-globals-jit the $_SERVER and $_ENV variables may or may not even > be available. > http://us3.php.net/manual/en/ini.core.php#ini.auto-globals-jit > > Thanks to request-order, the order of variables in $_REQUEST can be anything > - so if I want a specific combination of possibilities, I retrieve that > combination rather then hope that request-order was not changed from the > default 'GPC' > http://us3.php.net/manual/en/ini.core.php#ini.request-order > > $_POST is an even more interesting. If you disable $_POST - either by > setting variable_order to 'EGCS' to exclude posted data then filter_input > will not return any data for posted variables. auto_glabls_jit provides an > even odder edge case. With just in time creation enables, $_POST will not > be created when PHP is running unless you try to access something from the > array. This also affects whatever internal structure filter_input() uses > and filter_input() does not trigger the creation of post variables. So if > you call filter_input() after calling something like > isset($_POST['anynonexistantvariable'] it works. If you call it before it > does not. > > To safely deal with post you need to parse the post data from php://input .. > and for php://input is inconsistent in that depending on compile options it > may be possible to read it multiple times, or it may be deleted after being > read. > > > > > _______________________________________________ > New York PHP User Group Community Talk Mailing List > http://lists.nyphp.org/mailman/listinfo/talk > > http://www.nyphp.org/show-participation From ircmaxell at gmail.com Thu May 22 17:10:20 2014 From: ircmaxell at gmail.com (Anthony Ferrara) Date: Thu, 22 May 2014 17:10:20 -0400 Subject: [nycphp-talk] Promote Secure Coding In-Reply-To: <537E5C2E.3020908@gmail.com> References: <537CC1AD.50102@gmail.com> <537CE0CA.7090607@gmx.net> <537CE5C2.6060001@gmail.com> <537E0915.5070905@gmail.com> <537E5C2E.3020908@gmail.com> Message-ID: > Not bothering to address the rest of your comments since they seem to be based on a misunderstanding. No they are not. My point was that you shouldn't be doing `echo "Hello $name"` in the first place. So the rest of my comments actually fit right inline. Please give them another read, and see the justifications I used for saying people should not be using `echo "Hello $name"`, rather than dismissing me for saying that you shouldn't without even giving it a thought. Anthony On Thu, May 22, 2014 at 4:21 PM, Gary Mort wrote: > > On 05/22/2014 11:35 AM, Anthony Ferrara wrote: >> >> Gary, >> >> >>> Consider the secretary updating their company website. They have been >>> told >>> that they need some landing page to say "Welcome " at the top. >>> >>> The pages are mostly html with a bit of PHP here and there. So they go >>> to >>> an online tutorial, go through steps 1-4 where they learn about "hello >>> world" which is a simple little tutorial of >>> $name = $_GET['name']; >>> echo "Hello $name"; >> >> Who said to `echo "Hello $name"`? I sure didn't. > > > That was stated in my original post. I thought I was quite clear that this > method was for a specific class of users and I gave the example. > > This is the common instructional pattern for teaching others PHP. They > almost all start with "Hello World" and follow it with "Hello $name" where > $name directly from $_GET['name'] > > That's why I made an effort to avoid using the pronoun "you" when discussing > using this method. IE I did not say "you" should use this method meaning > Anthony... nor did I say "you" to refer suggesting people on this e-mail > list should use this method. > > The only time I deliberately use the word "you" is in the actual text of my > proposed "before you begin learning PHP programming" because there the > pronoun you refers directly to the individual who doesn't know PHP at all > yet. > > Not bothering to address the rest of your comments since they seem to be > based on a misunderstanding. > > _______________________________________________ > New York PHP User Group Community Talk Mailing List > http://lists.nyphp.org/mailman/listinfo/talk > > http://www.nyphp.org/show-participation From garyamort at gmail.com Thu May 22 17:35:25 2014 From: garyamort at gmail.com (Gary Mort) Date: Thu, 22 May 2014 17:35:25 -0400 Subject: [nycphp-talk] filter_input misconceptions In-Reply-To: References: <537E61A7.2030600@gmail.com> Message-ID: <537E6D9D.3020006@gmail.com> On 05/22/2014 05:02 PM, Anthony Ferrara wrote: We learned **years** ago that this doesn't work. Magic_quotes was removed because of that. Register_globals was removed. ETC. Yeah, and then filter.default was added back in AND in such a way that it can't be changed I guess "we" didn't really learn that it doesn't work. :-) > > The short of it, working around that setting is not going to work. > Many people tried working around magic_quotes. Fail. The only actual > solution is to set it to not do anything. Except that with filter_input you can actually get access to the original unfiltered data without having to do all sorts of checks. Just call filter_input($type, $filter) with whatever filter you want, including the raw filter which doesn't do anything. Unfortunately, at the moment there are cases where input_filter(INPUT_GET) will not return data and $_GET[] will return data. You actually have to call: if (!input_has_var(INPUT_GET, $varName) { isset($_GET[$varName]); } $var = filter_input(INPUT_GET, $varName, $filter); While that is not elegant I don't know of any instance where doing the above will not result in retrieving the correct data AND using $var = $_GET[$varName] will retrieve the correct data. Can you come up with a concrete example? > > Anthony > > On Thu, May 22, 2014 at 4:44 PM, Gary Mort wrote: >> It seems there are some misconceptions on the filter_* API. Recently I was >> contacted by a colleague when his website went off kilter. All of the >> sudden all the variables had extra html encoding charectors in them....and >> then since they were encoded a second time when displayed they would have >> even more. >> >> This was on a server I had worked on a few months previously and this was >> not happening. So I took a look at the configuration and discovered that >> filter_default had been changed. It turned out that PHP on the server had >> recently been upgraded from the CentOS repositories and the default settings >> changed. >> http://us3.php.net/manual/en/filter.configuration.php#ini.filter.default >> >> Looking into it a bit more, I experiemented with some different options on >> various settings which control the creation of the super global variables, >> after which I decided that it is better to use $var >> = filter_input(INPUT_GET, 'myvar', FILTER_UNSAFE_RAW); then $_GET in the >> future[though of course if in a framework which provides an interface to the >> http variables it is better to use the framework to be consistent] >> Note, FILTER_UNSAFE_RAW - this is not a security decision, it is a stability >> decision. >> >> First off, if you use $_GET then you ALSO are using the filter_input API. >> All global variables are populated by passing them through filter_input. By >> design, the default filter will be FILTER_UNSAFE_RAW however there is no way >> to change this from within your PHP code. It can only be set before the >> execution of the PHP script[either in the php.ini file or, with apache, you >> can set a custom ini variable in .htaccess]. >> >> Presuming my colleague gave me the correct information on where the upgrade >> came from, it seems that the latest CentOS PHP packages instead use >> FILTER_SANITIZE_FULL_SPECIAL_CHARS >> >> Since you[and by you I mean anyone publishing PHP code where they can't >> control the server configuration it will be executed on] can't get away from >> it being used, the best you can do is force it to do exactly what you want. >> IE if you want raw data, use filter_input and FILTER_UNSAFE_RAW so you make >> sure to get what you expect to get, and not something set by the server. >> >> In addition, the global variables $_GET, $_SERVER, $_ENV, $_SESSION, >> $_COOKIE, $_REQUEST, and $_POST simply can't be trusted. Only filter_input >> will give you access to the true data for 4 out of those 7 variables. It >> does not give you access to $_SESSION and while it does give you access to >> INPUT_POST but there are a couple edge cases where it will not provide the >> post data. >> >> The php.ini settings filter.default, track-vars, and variables-order can all >> change what is stored in the super globals. >> http://us3.php.net/manual/en/filter.configuration.php#ini.filter.default >> http://us3.php.net/manual/en/ini.core.php#ini.track-vars >> http://us3.php.net/manual/en/ini.core.php#ini.variables-order >> >> Without doing detailed checking of the various combinations from inside the >> code, there is no way to tell which of those variables actually has data and >> what filtering has already been done to them. In addition, $_SERVER may or >> may not include both $_SERVER and $_ENV variables[running google app >> engine's dev server they will be combined, when you are on the actual >> production server they are not] >> >> With auto-globals-jit the $_SERVER and $_ENV variables may or may not even >> be available. >> http://us3.php.net/manual/en/ini.core.php#ini.auto-globals-jit >> >> Thanks to request-order, the order of variables in $_REQUEST can be anything >> - so if I want a specific combination of possibilities, I retrieve that >> combination rather then hope that request-order was not changed from the >> default 'GPC' >> http://us3.php.net/manual/en/ini.core.php#ini.request-order >> >> $_POST is an even more interesting. If you disable $_POST - either by >> setting variable_order to 'EGCS' to exclude posted data then filter_input >> will not return any data for posted variables. auto_glabls_jit provides an >> even odder edge case. With just in time creation enables, $_POST will not >> be created when PHP is running unless you try to access something from the >> array. This also affects whatever internal structure filter_input() uses >> and filter_input() does not trigger the creation of post variables. So if >> you call filter_input() after calling something like >> isset($_POST['anynonexistantvariable'] it works. If you call it before it >> does not. >> >> To safely deal with post you need to parse the post data from php://input .. >> and for php://input is inconsistent in that depending on compile options it >> may be possible to read it multiple times, or it may be deleted after being >> read. >> >> >> >> >> _______________________________________________ >> New York PHP User Group Community Talk Mailing List >> http://lists.nyphp.org/mailman/listinfo/talk >> >> http://www.nyphp.org/show-participation > _______________________________________________ > New York PHP User Group Community Talk Mailing List > http://lists.nyphp.org/mailman/listinfo/talk > > http://www.nyphp.org/show-participation From ioplex at gmail.com Thu May 22 23:58:48 2014 From: ioplex at gmail.com (Michael B Allen) Date: Thu, 22 May 2014 23:58:48 -0400 Subject: [nycphp-talk] Proper Form Processing Techniques In-Reply-To: <537CE07F.3040103@gmail.com> References: <537A4211.4010105@gmail.com> <537CE07F.3040103@gmail.com> Message-ID: On Wed, May 21, 2014 at 1:21 PM, Gary Mort wrote: > > On 05/20/2014 04:24 AM, Michael B Allen wrote: >> >> >> I actually started out doing what you describe but I thought the >> server side code started to get a little messy so I thought I would >> break things up into add, remove, applyCode and so on. > > > Right, and you can still do that. Ie you have an add function, an applyCode > function, a remove function, etc. > > Then your update function just chains all 3 functions together. > > >> As for other's suggestions about storing state on the client by what >> is ultimately manipulating the DOM with JavaScript, I can see how that >> could be used to create sophisticated UI elements. But I don't think I >> would ever put any state on the client that I couldn't accept losing >> at any moment (e.g. as I type this, gmail is periodically saving this >> message with async requests). Even storing stuff in a cookie seems >> dubious for a shopping cart. > > > Actually, I find the best mechanism is to use a localDB data storage for > almost anything where you are storing data - but that means limiting your > code to browsers supporting some minimal amount of HTML5. > > By storing your "draft" data in a localDB, you then will have an easier time > converting your code from an online app to an offline app. > > For example, when I use the gmail interface, I enable it's offline mode so > all the draft data is saved to my local db. If I happen to be travelling on > the train with internet cutting in and out, then I can still compose e-mail > and it will be sent when I'm online again. I'm still not convinced. Imagine you're making a calendaring application and use local storage like you describe to draft events. Then imagine a scenario where a user tries to schedule an appointment while they're on the train and the internet cuts out. The appointment is not actually scheduled until they visit the site again which by then the event time may have already passed. Or maybe they used another device. A lot of people have multiple devices now. I think there certainly are cases where it is ok to store data on the client. But it should not be anything someone would get remotely upset about losing. And if it has to do with money, it's probably something someone would care about. Putting something in a shopping cart is a sort of transaction. You're saying I am willing to purchase this particular item at this price. At any point after that moment the item and/or price could change. The item could sell out. A sale could expire. Have you ever tried to buy plane tickets and a price changed on you while you're sitting at the computer fiddling with times trying to satisfy everybody's schedule? I think the airlines actually change prices depending on website activity for particular flights. Bastards! Mike -- Michael B Allen Java Active Directory Integration http://www.ioplex.com/ From ramons at gmx.net Fri May 23 07:27:36 2014 From: ramons at gmx.net (David Krings) Date: Fri, 23 May 2014 07:27:36 -0400 Subject: [nycphp-talk] Proper Form Processing Techniques In-Reply-To: References: <537A4211.4010105@gmail.com> <537CE07F.3040103@gmail.com> Message-ID: <537F30A8.9080709@gmx.net> On 5/22/2014 11:58 PM, Michael B Allen wrote: > > I'm still not convinced. Imagine you're making a calendaring > application and use local storage like you describe to draft events. > Then imagine a scenario where a user tries to schedule an appointment > while they're on the train and the internet cuts out. The appointment > is not actually scheduled until they visit the site again which by > then the event time may have already passed. Or maybe they used > another device. A lot of people have multiple devices now. > > I think there certainly are cases where it is ok to store data on the > client. But it should not be anything someone would get remotely upset > about losing. And if it has to do with money, it's probably something > someone would care about. It all comes down to clearly indicating "Hey, your stuff is not submitted to the server yet and it is as if you didn't do it." Disclosure and proper documentation is of importance here. One of the biggest misconceptions in software development is that there is no network latency and even more so that there is always a network. That is why the whole cloud stuff is only nice as long as Big Bubba with his steam shovel doesn't rip the cables out of the street somewhere. So the choice is to lose everything or store a local draft that depending on the nature of the item gets uploaded automatically to the server once connectivity is available again. I see your point with multiple devices, but that requires the user to understand that one device is not the same as the other. That concept is not new and only a problem if one doesn't know about it and if connectivity was not present during the entire process. To mitigate that allow the start of a task with results that need to be shared to happen only when connectivity is present and make a note of the task start on the server. If the connection craps out after that the server at least knows that it is waiting for something final and can display that fact on any other device...assuming that device has connectivity. Beyond that we get into having cake and eating it too territory as well as that no software in the world can fix management flaws. > > Putting something in a shopping cart is a sort of transaction. You're > saying I am willing to purchase this particular item at this price. At > any point after that moment the item and/or price could change. The > item could sell out. A sale could expire. That depends on how you design the cart. To be fair to customers do not allow them to add anything to the cart that is no longer available. And once placed in the cart mark that item as 'on hold' so that inventory is properly reflecting the potential buy. Sure, once the cart expires or the customer removes the item the product was held for nothing. I'd rather take that risk than having to make good on my promise...or always claim no rainchecks. Price change is a bit different, when the customer put the item in the cart they accepted that current price. You can be nice and honor a lower price on checkout (and eat the loss if the price went up), but important price fluctuations may exist for day traders on stock markets. Prices are quite stable for cucumbers and keyboards. In the end strive for the best user experience and assume that there is at least one user who does everything wrong...such as typing "abc" into a quantity field or typing 'May' or '234' into a numerical date field. Sure, that adds to complexity, but users generally don't care if you are miserable. > > Have you ever tried to buy plane tickets and a price changed on you > while you're sitting at the computer fiddling with times trying to > satisfy everybody's schedule? I think the airlines actually change > prices depending on website activity for particular flights. Bastards! Yep, they do...and that is another example. Competition and scarceness (there is only one plane that leaves at that time from that airport to that destination) do weird things. In the end it doesn't matter when they slam you with cabin door closing fees and moronic stuff like that. - David From glenn310b at me.com Fri May 23 11:14:55 2014 From: glenn310b at me.com (GLENN POWELL) Date: Fri, 23 May 2014 11:14:55 -0400 Subject: [nycphp-talk] PHP is not just for professionals In-Reply-To: References: <537E0E72.9010203@gmail.com> Message-ID: <70F1BBCF-64DE-4268-B4E4-B6754762323B@me.com> Gary and Leam, I also agree. Over the past few years I have worked on 3 ?homegrown? MVC frameworks. 2 of these were business applications (inventory, ERP, that sort of thing.) and that?s the use case I?m thinking of here. I didn?t design them or code them and had no involvement in the creation of them. My experience has been that it?s like learning whole new programming language that just happens to be built with PHP. Most of the development time is spent in figuring out how to get the framework to do what I want. (or rather, figuring out how the framework works.) These are/were proprietary frameworks so there is no ?community? to reach out to. On 2 of these, I have (at times) been the solo developer who has inherited the system after the creators left. One thing (among many) that I find makes it hard to work on these systems is the use of default behavior. Gary?s example; > > $app = Factory::getApplication(); > $app->execute(); > ====== I have no idea what that does until I read thru the code and find out what the default is. (or if I?m lucky, there will be some documentation.) On the surface, it tells me very little about what it?s doing. I?m currently working on re-designing one of these in the hopes of creating something that is easier to learn and work with. So far, the plan is to use an MVC pattern with controllers that read top down like an actual program. Mostly static ?helper? functions that take arguments and return something. Any dependencies are passed in as arguments. I?ll end up ?repeating myself? in these, particularly in ares like input checking, user auth, data access auth and so on. ?and for me, and for this application, I think that?s ok. I?m using objects only where I really need them, and avoiding extending on classes where possible. I?m hoping to end up with controllers that any competent programmer could read and understand quickly. Controllers that revel the flow of the application. Sort of like this; wrote: > Gary, > > I'd have to agree with you on this. We can be happy that PHP is now a professional grade enterprise capable solution. However, frameworks, "modern" coding practices, and a host of other things make it very difficult for someone to climb the learning curve. > > That may be just my perception. > > Leam > > > On Thu, May 22, 2014 at 10:49 AM, Gary Mort wrote: > Anthony's comments on my last post reminded me of an issue I feel PHP is facing today. > > ===== > > $app = Factory::getApplication(); > $app->execute(); > ====== > > -- > Mind on a Mission > _______________________________________________ > New York PHP User Group Community Talk Mailing List > http://lists.nyphp.org/mailman/listinfo/talk > > http://www.nyphp.org/show-participation -------------- next part -------------- An HTML attachment was scrubbed... URL: From chsnyder at gmail.com Fri May 23 13:07:03 2014 From: chsnyder at gmail.com (Chris Snyder) Date: Fri, 23 May 2014 13:07:03 -0400 Subject: [nycphp-talk] PHP is not just for professionals In-Reply-To: <537E0E72.9010203@gmail.com> References: <537E0E72.9010203@gmail.com> Message-ID: The subject line is hilarious, considering how many years it took to get PHP accepted as an enterprise-ready language. If it even is... On Thu, May 22, 2014 at 10:49 AM, Gary Mort wrote: > > It allows for a gentle learning curve, where you can go from little bits > of PHP to a complex set of conditions and actions on a single PHP page, and > then on to seperating code out into libraries of common functions but still > single pages, and finally to frameworks and obtuse programs such as > ===== > > $app = Factory::getApplication(); > $app->execute(); > ====== > > I love it. As if any single request would require multiple Application instances. But hey, you never know... Whenever I see complex patterns like this, I think "disgruntled Java coder." Frameworks help a lot, but the reason they are so helpful is also the reason why they tend to have a big learning curve: web development involves a LOT of suck. And by the time you abstract most of that suck away into the bowels of your framework, it has grown into a crazy beast of a thing that only you and your fellow devs (if you're lucky) fully understand. On the other hand, a sufficiently evolved framework can build anything, quickly. I'd rather not break my head on someone else's horrible attempt at MVC when I can just rebuild the site in my own horrible (but familiar!) attempt at MVC and move on. Controllers come and go, only the data lives forever. -------------- next part -------------- An HTML attachment was scrubbed... URL: From garyamort at gmail.com Fri May 23 13:40:26 2014 From: garyamort at gmail.com (Gary Mort) Date: Fri, 23 May 2014 13:40:26 -0400 Subject: [nycphp-talk] PHP is not just for professionals In-Reply-To: <70F1BBCF-64DE-4268-B4E4-B6754762323B@me.com> References: <537E0E72.9010203@gmail.com> <70F1BBCF-64DE-4268-B4E4-B6754762323B@me.com> Message-ID: <537F880A.8000401@gmail.com> On 05/23/2014 11:14 AM, GLENN POWELL wrote: > One thing (among many) that I find makes it hard to work on these > systems is the use of default > behavior. Ooo, I completely forgot about that. In Joomla! for my own sake I've been avoiding default actions. For example, in their MVC framework, if you don't specify the layout template, it will load the template file "default.php". My default.php file is: That way at least I can review the log files and discover when I have defaults being executed - and they don't break the application. IE the web page might have a blank spot displayed on it but there are no blank screens and no leaking of information. > So far, the plan is to use an MVC pattern with controllers that read > top down like an actual program. > One thing I tend to do nowadays is to use a modified drupal design pattern for views. For example: https://github.com/drupal/drupal/blob/7.x/modules/user/user-profile.tpl.php From top to bottom, the view starts with describing what it used for. Then it lists every variable it is expecting. What I don't use is the bottom section, I try to use mostly self contained views and I format them for my IDE: ---- user->isGuest()) ? 'World' : $app->user->username; // html markup is below, change it as much as you need to ?> ...lots of html markup...

Hello

Hello user->isGuest()) ? 'World' : $app->user->username; ?>

However that means the html code is tightly coupled to the framework. By creating local variables for any string values I am going to display, I can easily change frameworks by changing the top section. And by using shorthand notation in the html section, it makes the html readable by the secretary who took a high school course in html - so she is free to go in and modify the html for those minor changes that should not require a PHP programmer to make. > I have a top down controller that is readable and as self documenting > as possible. > > No default behavior and nothing obfuscated. > > I don't think this is a very popular approach these days but I do > think that it will serve well. > It doesn't bother me that it is not a popular style these days - what bothers me is that I often hear people refer to it as "bad code style" or "unprofessional". It's not an "enterprise" code style - that doesn't make it bad or unprofessional - it means it is not built to be maintained by an international team of hundreds of programmers. It's written to be maintained by a handful of programmers - which is exactly what a small business needs. To me it's unprofessional to implement a system where the cost is out of proportion to the business to maintain and modify. But then, I started programming back in the 1990's in an IBM town. I observed all the businesses that were pushed into adopting the SAP platform because it was "iso 9000" certified - only to end up conducting 80% of their business 'off the books' because it didn't fit into the default SAP configuration and SAP consultants charge 500+ an hour to customize it. I'm my own worse enemy when it comes to doing freelance because I don't try to push clients into implementing big expensive systems, and I don't make promises about it 'solving all your problems'. I often don't get the job in favor of someone who sells better... but in the end, I have to live with myself. -------------- next part -------------- An HTML attachment was scrubbed... URL: From garyamort at gmail.com Fri May 23 13:52:05 2014 From: garyamort at gmail.com (Gary Mort) Date: Fri, 23 May 2014 13:52:05 -0400 Subject: [nycphp-talk] PHP is not just for professionals In-Reply-To: References: <537E0E72.9010203@gmail.com> Message-ID: <537F8AC5.5060700@gmail.com> On 05/23/2014 01:07 PM, Chris Snyder wrote: > The subject line is hilarious, considering how many years it took to > get PHP accepted as an enterprise-ready language. If it even is... Thank you.... I was aiming for that as irony. :-) It's not that I think there is anything wrong with writing PHP programs in an enterprise style. For the enterprise, writing in that style is very important and has major cost benefits. It's just with all the focus on being "enterprise-ready" I often feel that a lot of decent PHP code is unfairly disparaged as bad just because it's not the "hip new way to code". From garyamort at gmail.com Fri May 23 13:59:02 2014 From: garyamort at gmail.com (Gary Mort) Date: Fri, 23 May 2014 13:59:02 -0400 Subject: [nycphp-talk] Proper Form Processing Techniques In-Reply-To: <537F30A8.9080709@gmx.net> References: <537A4211.4010105@gmail.com> <537CE07F.3040103@gmail.com> <537F30A8.9080709@gmx.net> Message-ID: <537F8C66.3080000@gmail.com> On 05/23/2014 07:27 AM, David Krings wrote: > > > I see your point with multiple devices, but that requires the user to > understand that one device is not the same as the other. That concept > is not new and only a problem if one doesn't know about it and if > connectivity was not present during the entire process. Actually, depending on the browser these days, it might not even matter. I know that for myself, I can work on any computer in the house or my cell phone and my local data will be the same on all of them. But then, I use Google Chrome and an Android phone - so everything automatically synchs between devices. Though to be completely honest, the real reason I write code using local data for many situations is because it's fun. :-) When doing anything professionally, I always have to weight the options and choose the best option for the client. IE doing something that will take twice as long to code "because it's fun" is the wrong decision - it has to have business value. Doing something that will take the same amount of time to code "because it's fun" is the right decision because if I'm having fun programming, I'm more effecient. From zaunere at gmail.com Tue May 27 13:19:38 2014 From: zaunere at gmail.com (Hans Z) Date: Tue, 27 May 2014 13:19:38 -0400 Subject: [nycphp-talk] cnvyr.io public API Message-ID: Hi all, I've opened up an API I've been using for a while. http://cnvyr.io It should help to offload image and CSS/JS processing for other developers, and I plan on keeping it open as long as usage doesn't start costing me an arm and a leg :) Let me know if any problems - thanks, H