Coding Horrors: PHP - Magic Quotes
Ah, magic quotes, one of those terrible not thought through PHP anti-features, not to mention overly blogged about (but hey, hopefully this post can provide some additional insights on this evil, this abomination to the Lord) - but at least its deprecated as of PHP 5.3 and will apparently be removed with the fabled coming of PHP 6 (and there will be no pain and suffering no illness...)
For those of you who came in late - Magic Quotes (like Anakin Skywalker), was initially intended for good and on a lot of websites it still provides some protection (unknowingly to some) against the mediocre "SQL Injection" issue - basically it escapes all values within the GET/POST & COOKIE globals, which automatically makes these strings safer (not completely safe) to use.
But what is so evil about all of this?
- Its unnecessary to escape everything, which means an unnecessary performance sacrifice - its not like everything will always be inserted into/selected from a database.
- It also becomes rather annoying since we won't even (on the values that actually require escaping) always do a direct insert into the database either, chances are that we will display or do some validation on values before inserting it, which means we need to unescape values an re-escape values - defeating the whole purpose.
Let me explain this issue using three scenarios.
Scenario 1:
You're in the process of "building" or rather (in your case) downloading pieces of code/scripts that will eventually be your website/ web application.
You download the source code for forum A (which requires magic quotes), and the sources for blog B (which doesn't use magic quotes).
Disabling magic quotes will leave forum A vulnerable, enabling magic quotes will potentially screw the input/output to blog B.
In this scenario you might at least have the choice to simply download other scripts that don't require magic quotes, or vice-versa.
Scenario 2:
You start at a new company and inherit the most horrible source code ever conceived and constructed by mankind.
The developer(s) that developed (more like mangled) the code either firmly believed in magic quotes or didn't know any better.
Forcing you to either continue the downwards spiral (dev using the same style), or do things following certain/better standards - forcing you to code around the "cest pool" they like to call code.
In this scenario you are forced to work with what you've got.
Scenario 3:
You become senior developer at a web dev company with 1000's of custom built sites, 90% of these sites require magic quotes - you warn the managers and tell them that with the coming of PHP 6 all scripts that use magic quotes will go to hell.
Unfortunately they pretty much ignore you and the next day some clever system administrator decides to disable magic quotes on all servers - while he/she neglected to make any backups for the last 10 months.
All of a sudden the phones start to ring wildly and out of control, customers demanding answers to why you lost all their data.
In this scenario you're screwed...
How do we solve these scenarios?
All over the web you can find tons of "solutions", like the following dangerous snippet (and invert versions of the script):
function stripslashes_deep(&$value) { $value = is_array($value) ? array_map('stripslashes_deep', $value) : stripslashes($value); return $value; } if((function_exists("get_magic_quotes_gpc") && get_magic_quotes_gpc()) || (ini_get('magic_quotes_sybase') && (strtolower(ini_get('magic_quotes_sybase'))!="off")) ) { stripslashes_deep($_GET); stripslashes_deep($_POST); stripslashes_deep($_COOKIE); }
The preceding snippet basically unescapes values, returning values in a "magic quotes off" manner - I believe(hope) that the true reason the author wrote this script is for scenarios where you can't for some dodgy reason disable magic quotes.
The danger of scripts like this is when you implement them without considering the codebase you're using - like seen in scenario 1 - 3.
So how (in my opinion) do we actually solve this issue?
When confronted with legacy code, over which you have no control or have no time to fix millions of lines of code, the safest bet is to unfortunately keep magic quotes enabled, data integrity is paramount.
Always write your code to function with & without magic quotes, don't ever rely on magic quotes but cater for its unfortunate existence, for example:
define('MQ_ENABLED', ((function_exists("get_magic_quotes_gpc") && get_magic_quotes_gpc()) || (ini_get('magic_quotes_sybase') && (strtolower(ini_get('magic_quotes_sybase'))!="off")))); function value($name) { if (isset($_POST[$name])) { return (MQ_ENABLED) ? stripslashes($_POST[$name]) : $_POST[$name]; } return null; }
Thinking back about the brainwave behind this anti-feature, why stop at Magic Quotes? What about Magic numbers? (Prevent our integers from being turned into malicious queries) or all kinds of "Magic" XSS attack protection - why not just for the hell of it html encode everything while we think we're being helpful?
The horror!
Posted by - Christoff Truter
Date - 2010-09-28 16:12:34
Comments - 1
Date - 2010-09-28 16:12:34
Comments - 1
C# Threading: Semaphore
In previous posts we had a quick look at the Mutex / Monitor classes, which limit our apps to only allow one thread to access a resource (critical section) at a time.
But what about scenarios where we work with a pool of resources? In scenarios where we need to limit the number of threads that uses a pool of resources.
One solution would be to simply modify a mutex/monitor to almost act like traffic control. Observe the following rather dodgy snippet that attempts to solve this problem (don't use)
using System; using System.Threading; using System.Linq; public class Program { static int _maximumThreads = 3; static object locker = new object(); static void WaitOne() { while (true) { lock (locker) { if (_maximumThreads > 0) { _maximumThreads--; break; } } } } static void Release() { lock (locker) { _maximumThreads++; } } public static void Worker() { WaitOne(); Console.WriteLine("{0} Enters", Thread.CurrentThread.Name); Thread.Sleep(3000); Console.WriteLine("{0} Exists", Thread.CurrentThread.Name); Release(); } public static void Main(string[] args) { for (int i = 0; i < 8; i++) { Thread thread = new Thread(Worker); thread.Name = String.Concat("Thread ", i + 1); thread.Start(); } } }
We start out with an initial thread limit of three - which means we only want three threads to enter the resource pool at a time (regulate our traffic).
Within the WaitOne method we decrement the number of allowed threads and simulate some work using the Thread.Sleep method and once we're done we call the Release method where we increment our number of threads (since we're essentially done with that slot - making it available again).
Fortunately there is a much simpler/cleaner way to do this - Microsoft added a Semaphore class to .net to aid is in this process, in the following snippet we rewrite the snippet using the Semaphore class.
using System; using System.Threading; using System.Linq; public class Program { private static Semaphore _resourcePool; private static int _maximumThreads = 3; public static void Main(string[] args) { _resourcePool = new Semaphore(0, _maximumThreads); for (int i = 0; i < 8; i++) { Thread thread = new Thread(Worker); thread.Name = String.Concat("Thread ", i + 1); thread.Start(); } _resourcePool.Release(_maximumThreads); } private static void Worker() { _resourcePool.WaitOne(); Console.WriteLine("{0} Enters", Thread.CurrentThread.Name); Thread.Sleep(3000); Console.WriteLine("{0} Exits", Thread.CurrentThread.Name); _resourcePool.Release(); } }
Note that Initially the main thread owns all slots in the Semaphore, that is why we need to call the Release method in the main thread.
The Semaphore class is similar to the Mutex class in that it allows you to create named and unnamed Semaphores, which means that we can limit our resource pool cross application processes like we can do with the Mutex class.
Additional Reading:
http://msdn.microsoft.com/en-us/library/system.threading.semaphore.aspx
Posted by - Christoff Truter
Date - 2010-09-18 22:51:47
Comments - 0
Date - 2010-09-18 22:51:47
Comments - 0
First 11 12 13 14 15 16 17 18 19 20 Last / 62 Pages (124 Entries)