User agent string for "[browser version] and later" - php

I'm trying to avoid tons of PHP code by specifying that a remote stylesheet, containing CSS animation, should be loaded if the HTTP_USER_AGENT string corresponds to [browser version x] or later. For example, knowing that CSS animations are supported in Chrome 19 and newer, the code would detect if Chrome's version is greater than 19, and load the appropriate stylesheet.
Is this feasible at all using PHP?

This is one solution, but you will have to update your parser for the user agent string from time to time to include changes therein.
There is no agreed standard for use agent strings, so in general parsing the user agent string is quite hard and often comes down to lookup tables.
A more future-proof approach would be to detect the support of CSS animations on the client side using, e.g., Modernizr and then load the stylesheet based on the result. That way you don't care, if some browser developer wants to change the (structure of the) user agent string in the future.

If you must use PHP for this, then there is a built-in function get_browser() that does what you want.
However... If you use get_browser(), be aware that it is a bad solution to your problem.
In order to user this function, you must have an up-to-date browsecap.ini file, which is basically a text file that defines the capabilities of every browser and every version ever released.
The downsides of this are obvious:
You have to find and install an up-to-date copy of browsecap.ini in the first place.
You have to update it every time a new browser is released (and new versions are coming out frequently, so this is quite a big task).
It might not include all features that you want to detect.
It will break if the user masks their user agent string.
For all these reasons, I strongly recommend not using get_browser(), or indeed any PHP-based or server-side solution.
Instead, as others have said, you should investigate using the Modernizr library. This is a Javascript library that you install on your site that does feature detection in the browser. It will never be out of date, because it looks specifically at whether the features are supported, so it doesn't care what the actual browser is.

You may wish to consider using a Device Description Repository (DDR). This is an application or Web Service that you can pass in an User Agent String and get a list of known capabilities for that User Agent.
The benefits to this is that you will not have to keep updating your own code as new User Agents come about.
I read about DDRs recently in Dino Esposito's MSDN article on Mobile Site Development. He has an excellent write-up on the capabilities and nature of DDRs.
I realize you are doing PHP, but connecting / querying a DDR should be language independent.
Just a thought, hope this helps.

Related

Is it better/faster to detect mobile browser on server side (PHP) or client side (Javascript)?

I've seen code that detects whether someone is using a mobile browser in Javascript (e.g. a jQuery script) and I've seen some that work in PHP (or other server-side language). But I've never seen a good explanation for whether one is a better choice than the other in all or any situations. Is there a reason why one is a better choice?
The typical answer: it depends on why you are doing the check...
From my standpoint, here is what I usually consider:
If you want to present the user a different experience (mobile, tablet, laptop, etc) based on browser, do it at the server.
If you want to present the same general experience, but need to account for browser compatibility issues, do it at the client.
It is also considered by some in the UX field to be "bad form" to present the user an empty page and fill it in dynamically. Instead, a preliminary page should be populated and content can be dynamically added or altered. If this is a concern for you, a combination of server side and client side may be necessary.
I'd say the better way would be on server side, because for Javascript you need to wait until the page is rendered, while on server side it happens before.
If you're trying to detect this in order to do decide what javascript features are available, you'll have greater accuracy, without any major loss of speed if you do this in JavaScript.
If you're going to completely change what sort of page is rendered, like a full website or a mobile website, you're better off doing this server side.
As Ricebowl stated, never trust the client. However, I feel that it's almost always a problem if you do trust the client. If your application is worth writing, it's worth properly securing. If anyone can break it by writing their own client and passing data you don't expect, that's a bad thing. For that reason, you need to validate on the server.
Is green better than red?
Everything has its benefits and drawbacks. For example, doing it server side is more reliable, doing it client-side means less work for the server.
In fact, the client may have JavaScript disabled (see the NoScript extension for Firefox, and ScriptNo for Chrome, that allows a smart user to only enable JS on sites where you actually need it - a nice side effect is that it also eliminates almost all ads these days, as they largely seem to rely on JS from third party domains now). So just using the User-Agent string is more reliable, but less flexible.
If you work JS-heavy, you might get away with a dumb server, i.e. you do not need slow PHP, but you can serve all your data with high-performance static serving, through the various CDNs etc. - but anything that requires JS will work less good with search spiders, and some users will likely just block it.
As a web developer, UX and UI programmer I figure if anyone wants to change their UA, it's fine. They get to deal with the incompatibilities. As for a mobile vs desktop I would recommend the light version of browscap.ini instead of searching for device check for ismobiledevice. The if statement will be true or false, then you can also check tablet also. In the if mobile clause check the istablet key in the associative array. You can use it for phone or tablet css.

A secure method for premium php cms

Ok, I am in the process of creating a cms. There will be a free version, and a premium version. Obviously the premium version will have modules and such that the free version does not have. Does anyone have an idea on how i can prevent my premium version from being shared across the web? Ive looked into using a license key with remote server validation, as well as encrytion, and encoding the premium scripts. I dont want to use Zend Guard or Ioncube, because i dont want users to have to have that software installed just to ues the cms. I also want the cms to be customizable which rules out encoding. Anyone have ideas to prevent the scripts from being nulled? If its possible to maybe just encode a single page that does remote validation... just something... It doesnt have to be a bullet proof thing.. but something that prevents novice crackers from nulling it and releasing it
ENCODING PAGES:
Personally, I have tried a few techniques to avoid PHP encoders but nothing was really effective in a commercial environment.
Based on my experience though, I wouldn't worry so much about Ioncube and Zend not being installed on servers because most managed environments will most likely already have both, this is what I have found anyway. Because of this it reduces the problem of users to have to install it for a single application.
In saying that it depends on your target market also, if you're going head-to-head with the likes of Joomla! or WordPress for example, then your target market typically uses a managed environment so no big issue.
If you're however going for say an intranet market this could be a minor problem but any server admin worth a grain of salt will be able to install this easily without fuss, they will also understand why you put it in place. Note, the intranet market is a bit harder as you will need to specify port settings to check the license in your licensing module.
SIDE NOTE: As your product is going to be distributed with source code available you do need to be careful and pay attention to your Intellectual Property (IP), this generally means putting a legal disclaimer on every page that is readable. Also, don't forget to respect the requirements of other IP owners scripts you may be using in your project.
LICENSING & ENCODING (THE SUGGESTION):
Encoding a single page with licensing functions is a way of going about it but you will find it fairly easy to bypass if the rest of the source code is available.
What I would look at is encoding a single page with licensing functions but also encoding your login validation, half of your authentication checks for each protected page and some basic functions for posting to the database also. This way if they try to remove your encoded page with the licensing script there is no login or updating of content - plus they will get kicked out of the system as only half of your session checking will be valid - I hide a kill function nested into another function that is required for each page to operate, this may be a menu (this is great because you can hide the function with the logout), it just looks like part of the log-out function but in reality it is a function to destroy the session if not all variables are present.
When choosing values for your authentication checks on each protected page (that function should be encoded), try using what appears to be a random variable and non-descriptive names then encode the variable (I like MD5 hashes for this). It is another way to give more security around the 'hacking' of your script.
I hope this may help you and sorry that I cannot recommend a better solution.

Using eval() to enhance security

I admit the title is mostly a catch 22, but it's entirely relevant, so please bear with me for a while...
Background
As some may know, I'm working on a PHP framework whose major selling point is that of bridging functionality between different CMSes/systems.
From a developer perspective, there's an extensive error handling and logging mechanism.
Right now, there are two settings, DEBUG_MODE and DEBUG_VERBOSE, which control debug output.
The mode describes the medium and verbose controls the amount of detail.
To make it short, there's a mode called "console" which basically dumps debug info into the javascript console (which is now available in a major web browser near you).
The Issue
This [debug system] works great for development servers, but you absolutely cannot use it on a production one since debug details (which include DB credentials etc) get published publicly. And in all honesty, who ever migrated from a dev. to a prod. server flawlessly each time?
Solutions
Therefore, I've been trying to figure out a way to fix this. Among my proposed solutions are:
Having a setting which tells the framework to enable logging only if the request comes from a certain IP. The security issues for this are quite obvious (IP spoofing among others).
Having a setting which contains PHP expression(code) that gets eval'd and it's return used as a yes/no. The best part is that the framework installed may suggest CMS-specific expressions, eg:
Wordpress: current_user_can('manage_options')
Joomla: $user=&JFactory::getUser() && ($user->usertype=='Super Administrator') || ($user->usertype=='Administrator')
Custom: $_SERVER['REMOTE_ADDR']=='123.124.125.126'
These are among the two, I'm eager to hear out more suggestions.
So, do you think eval() should be up to it? I'll ensure it still performs well by only doing this once per page load/request.
Clarification
if(DEBUG_MODE!='none')echo 'Debug'; // this is how it is now
if(DEBUG_MODE!='none' && $USER_CONDITION)echo 'Debug'; // this is how it should be
The $USER_CONDITON allows stuff such as running is_admin() to allow all admins to see debug info, or, getUser()->id==45 to enable it for a specific user. Or by IP, or whatever.
Go ahead. It's evident that you understand the hypothetical security implications. In your case it's just important to tell the target user base about it.
As for the practicability of your approach, there's no discussion really. You need variable authentication logic and can't hardwire it to one specific environment/cms runtime.
The only concern you see is about performance. That's baloney. Not an issue. The presence of eval is what discerns scripting languages from compiled languages. If it's available you can not only use it, but can be sure that it's not going to be slow because a compiler+linker run is required behind the scenes. PHP takes some time with initializing its tokenizer and parser, but parsing itself is surprisingly quick.
And lastly, avoid such question titles on SO. ;} Or at the very least talk about create_function please.
IP spoofing long enough to actually get a response is unlikely to occur. If a user manages to build up a connection to your server, spoofing an internal or privileged developer IP they control your router, so you've got other things to worry about.
Rather than running eval can't you just write an anonymous function/closure: http://php.net/manual/en/functions.anonymous.php
(putting it in a config file, rather than web screen, writing complicated PHP code on a web form seems sub-optimal anyways)
Allowing free-form input of PHP code that gets executed - be it through eval() or create_function() - is simply bad design, and opens a big potential vulnerability for no good reason. It also opens the possibility of crashing a page through syntax errors.
Even the argument that the administrator can install plugins anyway doesn't hold entirely, because XSRF attacks are conceivable that manage to get malicious stuff into a text field (one request), but can't trigger a plug-in installation.
So no, I wouldn't do it; I would implement each CMS bridge as an adapter instead, and let the user choose the adapter (and if necessary enter some custom, sanitizable settings) from a pre-defined list. (Something similar was also suggested by #Wrikken in the comments)
It's your call. Chances are you will never have a problem from doing this the eval() way. And it can be argued that most of the CMSs you will be connecting with (Wordpress, Joomla) allow arbitrary execution of PHP code in the back-end anyway. But it's not good design.
Having a setting which contains PHP expression(code) that gets eval'd and it's return used as a yes/no. The best part is that the framework installed may suggest CMS-specific expressions, eg:
eval() may crash your page if any function doesn't exist or on any number of parse errors. And if bugs exist which allow user-supplied input (such as a uri requested) to even touch these evaled values, it will potentially open up your site to malicious or accidental destruction. Instead to identify the currently working framework, look for markers in the framework you're trying to bridge to, such as certain constants, functions, classes, etc. You can replace all your eval() functions with safe checks using function_exists(), defined(), etc.

PHP mobile browser detection?

I'm in need of a way to detect mobile browsers server-side. I'd like a way that requires me to do little to set up and little to maintain, yet still provide me with accurate detection of (at the VERY least) Android, Mobile Safari and Blackberry browsers, along with alternatives like Opera.
I'd like to have at least the majority of the mobile market covered, and I'd really prefer virtually all of the market if it doesn't take much.
WURLF is the ultimate way for mobile browser detection and a PHP API is available.
I found this one to be very easy to use php-mobile-detect
(edit: for now the Browser Capability Project is closed, i.e. atm this answer is not an option)
All you need is get_browser() and a recent browscap.ini that maps the user-agent string to a browser/version and its capabilities.
You can get a usually very up-to-date browscap.ini version from http://browsers.garykeith.com/downloads.asp
Its just a matter of reading the headers ( How do I read any request header in PHP ) and parsing / interpreting this to read the "user-agent", you may be able to find an existing PHP script or maybe just plain regex that will help in figuring out which user-agents are mobile and which are regular pc's / laptops.
There are a lot of different headers, as it indicates the operating system, so as many different mobile OS'es as there are there would be user-agent headers so the script needs to have a list of all valid ones.
http://en.wikipedia.org/wiki/List_of_user_agents_for_mobile_phones
Found this library a little while back:
http://code.google.com/p/mobileesp/
Has PHP, Java, JavaScript, and C# versions. I see it as a "lightweight" smartphone/tablet detection tool without dependencies and is regularly updated. I have mixed feelings about it though as some aspects of the code quality are a bit shaky.
If you need something even lighter-weight, the WP Super Cache plugin for WordPress contains some long regex strings you could probably swipe.
Browser sniffing based on user agent strings is always going to be flaky. I looked at WURFL and it is several MB compressed. Using that is overkill. A better approach is to detect the top devices in use on the website, design for those devices, and then call it a day.
A quick Google search picks up these:
http://mobiforge.com/developing/story/lightweight-device-detection-php
http://code.google.com/p/php-mobile-detect/
Zend Framework introduced Zend_Http_UserAgent lately.
It can determine the Mobile Device and it's capabilities by detecting the UserAgent through Wurfl, TeraWurfl and DeviceAtlas API.
How about http://code.google.com/p/hdapi/ ? Server side mobile detection in PHP.
Unfortunately WURFL is not free anymore for commercial projects.
But there is OpenDDR with its experimental PHP implementation.
I once used to store temporarily visitors' ip-addresses and csrf-session values (meant to count current visitors).
And I noticed that I had a side-gain of being able to see if the visitor used a mobile or a PC: The csrf of a mobile changes with every new page load, a PC doesn't; and the ip-addresses remain in both cases.
Sure, you only detect a mobile if a visitor clicks twice and I have not checked how reliable this is (as I do not really need it), but it is php/server-side only.

Changing web content based on browser type

I'm writing a web application and I'd like to work out what type of browser/OS the request is coming from, and customise the returned content accordingly. So if someone visits the site from an iPhone/Android, they get a more streamlined experience, or if it's a desktop, they get the full version. I will pretty much take a completely different path, rather than try to mix the content together.
What is the recommended approach for this in ASP.NET/IIS and PHP? Is there a single place I can catch incoming HTTP requests, make a decision, then redirect? Or is this usually done on a page by page case? Any gotchas I should look out for?
Edit: A good point was made to make sure there is a link to the full version on the reduced version. That's a good point, but raises the problem that once the user make this choice, all future redirections now have to point to the full version. I'd really rather be doing all of this in one place.
Cheers,
Shane
ASP.NET has a built-in browser detection mechanism. It's driven by a fully extensible collection of XML files (*.browser) that contain regular expressions for matching the incoming User-Agent string and associated properties for the matched agents.
You can access the properties from the Request.Browser object; you can also tag control properties based on browser specifics.
There's a bunch of info on the Web about this -- I also cover it in detail in my book: Ultra-Fast ASP.NET.
Not a direct answer but it's worth checking out CSS media types. You can specify the handheld type to streamline the page for phones and other small screened devices.
http://www.w3.org/TR/CSS21/media.html
You could take a look at the UserAgent header in the HTTP request and redirect accordingly.
In PHP that would be $_SERVER['HTTP_USER_AGENT'].
You should however watch out that you don't write a lot of duplicate code when doing this.
For ASP.NET applications you can check out the Global.asax file and Session_BeginRequest event.
You should probably look at Conditional Comments:
http://msdn.microsoft.com/en-us/library/ms537512%28VS.85%29.aspx

Categories