Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Events
Videos
Audiobooks
Packt Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials

7018 Articles
article-image-data-modeling-naming-standards-ibm-infosphere-data-architect
Packt
24 Dec 2009
4 min read
Save for later

Data Modeling Naming Standards with IBM InfoSphere Data Architect

Packt
24 Dec 2009
4 min read
The Prime-Class-Modifier Words Pattern Prime words represent key business entities. In an insurance business, examples of prime word are policy and coverage. A class word is a category that qualifies a prime word; for example, in policy code name, code is a class word. policy code can further be qualified by a modifier word; for instance, previous policy code where previous is the modifier word. You can define your own naming pattern different from the above modifier prime class pattern for a specific modeling object, including the separator between words and if modifier word or class word in the pattern is optional. You can have, for instance, modifier?_prime_modifer?_class_modifier? pattern for attribute naming in a logical data model. The ? characters indicate the words are optional and the separators are _. An example name with that pattern is permanent employee last name, assuming we have defined in our standard that permanent as a modifier word, employee as a prime word, last a modifier word, and name as a class word. Note that we don’t have the last optional modifier word in this example. In a different business (not insurance), code might well be a prime word and policy might not be a prime word; hence the need to define your own specific list of prime, class and modifier words and naming patterns for their application, and that is what you build in glossary model. Building Glossary Model The InfoSphere Data Architect (IDA) allows you to build a glossary model from blank or from pre-defined enterprise model. Creating glossary model and selecting its template, blank or pre-built enterprise template The enterprise glossary model gives you a head start with its collection of words relevant across various business types, most of which would probably be applicable to your business too. You can customize the glossary: change or delete the existing words, or add new ones. Selecting an existing word or words in the list and then clicking the cross icon will delete the selected words   Clicking the plus icon allows you to add a new word into the glossary   When you add a new word, in addition to the name, you specify its Abbreviation, Alternate name, and most importantly its type (CLASS, PRIME) and if it is a Modifier word. When the glossary is applied for transforming a logical to physical model, the abbreviation is applied to the physical modeling object. Customizing a word being added   Selecting the type of a word   Before we can apply the words to naming our data model objects, we need to define the naming pattern. You can define the naming pattern for logical and physical modeling objects. The sequence of the word types in the pattern from top to bottom is left to right when you apply them in the names. You can also choose the separator for your naming pattern: space or title case for the logical model, and any character for the physical model (most preferred choice would be non alpha numeric character that is not used in any of the words in the glossary). Defining pattern for logical model objects (entity and attribute)   Defining pattern for physical model objects (table and column)   Specifying separator for logical model   Specifying separator for physical model You then choose the glossary model that you want to apply to your data models. Glossary Model.ndm in the packtpub directory is applied   When you have finished building your glossary model and defining naming pattern, you can then apply them for naming your modeling objects. (You can further adjust the words in the glossary them when such a need arises)
Read more
  • 0
  • 0
  • 7912

article-image-dialog-jquery-user-interface-17
Packt
24 Dec 2009
4 min read
Save for later

The Dialog in jQuery User Interface 1.7

Packt
24 Dec 2009
4 min read
Traditionally, the way to display a brief message or ask a visitor a question would've been to use one of JavaScript's native dialog boxes (such as alert or confirm) or to open a new web page with a predefined size, styled to look like a dialog box. Unfortunately, as I'm sure you're aware, neither of these methods is particularly flexible to us as developers, or particularly engaging for our visitors. For each problem they solve, several new problems are usually introduced. The dialog widget lets us display a message, supplemental content (such as images or text), or even interactive content (like forms). It's also easy to add buttons, such as simple ok and cancel buttons to the dialog and define callback functions for them in order to react to their being clicked. The following screenshot shows a dialog widget and the different elements that it is made of: A basic dialog A dialog has a lot of default behavior built-in, but few methods are needed to control it programmatically, making this an easy to use widget that is also highly configurable and powerful. Generating the widget is simple and requires a minimal underlying markup structure. The following page contains the minimum markup that's required to implement the dialog widget: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html lang="en"> <head> <link rel="stylesheet" type="text/css" href="development-bundle/ themes/smoothness/ui.all.css"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>jQuery UI Dialog Example 1</title> </head> <body> <div id="myDialog" title="This is the title!">Lorem ipsum dolor sit amet,  consectetuer adipiscing elit.Aenean sollicitudin. Sed interdum pulvinar justo.  Nam iaculis volutpat ligula. Integer vitae felis quis diam laoreet ullamcorper.  Etiam tincidunt est vitae est.</div> <script type="text/javascript" src="development-bundle/jquery-1.3.2.js"></script> <script type="text/javascript" src="development-bundle/ui/ui.core.js"></script> <script type="text/javascript" src="development-bundle/ui/ui.dialog.js"></script> <script type="text/javascript"> $(function(){ $("#myDialog").dialog(); }); </script> </body> </html> Save this file as dialog1.html in the jqueryui project folder. To use the dialog, the following dependencies are required: ui.all.css jquery-1.3.2.js ui.core.js ui.dialog.js The dialog widget is initialized in the same way as the other widgets we have already looked at—by calling the widget's plugin method. When you run this page in your browser, you should see the default dialog widget as shown in the screenshot at the start of this article. As with the previous widgets we've covered, a variety of class names from the CSS framework are added to different elements within the widget to give them the appropriate styling for their respective elements, and any additional elements that are required are created on the fly. The following screenshot show these classes and the structure of the widget as interpreted by Firebug:   The dialog in the first example is fixed both in size and position, and will remain in the center of the viewport until it is closed. We can make the widget draggable, or resizable, or both easily. All we need to do is include the draggable and resizable component's source files with the other < script> resources at the end of the < body>.   It's not important that the draggable and resizable files are included in the page before the dialog's source file, they can come before or after and the widget will still inherit these behaviors. Any styling that is required, such as the resize indicator that appears in the bottom-left of the dialog, will be picked up automatically from the master CSS file.   Add the following two < script> elements directly before the closing < /body> tag in dialog1.html:   <script type="text/javascript" src="development-bundle/ui/ui.draggable.js"></script> <script type="text/javascript" src="development-bundle/ui/ui.resizable.js"></script>   Save this as dialog2.html and view it in a browser. The dialog should now be draggable and can be moved to any part of the viewport, but will not cause it to scroll if the widget is moved to an edge. The dialog should also be resizable—by clicking and holding the resize indicator the widget can be made bigger or smaller. If the dialog is made bigger than the viewport then it will cause the window to scroll.  
Read more
  • 0
  • 0
  • 1791

article-image-photo-compositing-gimp-part-2
Packt
07 Dec 2009
5 min read
Save for later

Photo Compositing with The GIMP: Part 2

Packt
07 Dec 2009
5 min read
Adding Realism to the Image As of the current state of our image, it’s almost done.  But we could still do something about adding even more believability to it than just our “2-d object on hand” setup here, right? First thing to consider is that photographed scenes aren’t actually as clean-looking as they are and as compared to common CGish images.  Just to break this cleanliness apart, let’s add in a simple cloud noise to our heart.  If that still doesn’t work for you, you could go ahead and paint over some details like cracks, dirt, etc.  This is to simulate the wear and tear effect that is always present everywhere we look at. To add this texture, let’s first create a new transparent layer to work on and let’s call it “texture” or something much more meaningful to you and easier to remember.  This will be the layer that will hold the cloud texture to use for the heart.  After adding this new layer, right click on the image window and select Filters > Render > Clouds > Solid Noise (as seen in the screenshot below). Creating the Texture Again, a pop-up window will appear wherein you can input values for the noise. This will entirely depend on your preference.  This fill then fill-up the entire layer with the cloud noise texture that we’ll use as overlay image for the heart later on.  Check the screenshot below for my settings. Cloud Noise Options You’ll notice now that what we see is just pure texture which is not what really wanted.  Instead we’ll use it as an overlay effect on top of our layer stack.  Let’s do this by changing the layer mode from Normal to Overlay then let’s adjust the opacity of the texture layer to something relevant and subtle. Texture Overlay However, we notice that the texture is affecting everything in our image including the hand and the cloth.  But we only want the heart to be affected by the texture.  We can do this in a couple of ways: the easiest would be to use the Eraser Tool to erase portions of the texture layer so we only leave the part of the heart, but doing this though will add more layers of undo levels everytime we stroke our eraser. What if we wanted to only have this single layer to work on yet have the flexibility as though we were switching from two layers (an original and a duplicate).  With this in mind, I think it’s time we use Layer Masks for more flexibility over our layer management. To apply our masking, let’s first create a selection to exclude the other parts of the image other than the heart, do this by right clicking on the heart layer then selecting Alpha to Selection. What this will do is select regions of the layer where it is opaque, in this case we’re only selecting the heart shape. Creating the Heart Selection Now with the heart shape selection active, let’s go back and activate our layer texture from which we’ll be creating our layer mask on (be sure that your selection is still active or else it will defeat the purpose of even creating it in the first place).  Right click on the texture layer and select Add Layer Mask (see screenshot). Creating a Layer Mask With the pop-up window that appears, select Black (full transparency) then press Add.  You’ll then notice that the effects the texture has are gone now, that’s because we filled the whole layer mask up with color black (which means full mask), making everything in the layer appear as nothing.  But since we want the current heart selection to have an effect on the layer, we’ll do the reverse instead, by filling up the selection with color white (#FFFFFF). Do this by selecting the layer mask, and not the layer itself, then use the Bucket Fill Tool to fill the selection with white.  Now we’ll notice the effects take place. Applying the Layer Mask   We’re only one step close to finishing the compositing here (yes, finally!). If we’re lucky enough to have gotten this far and not got bored the hell out of us, there’s one thing believably missing in our composition here, and that is the way the two fingers seem to be blocked by the heart (which shouldn’t be).  We should instead see the fingers somehow embrace parts of the heart. With all of our settings for the heart (highlights, shadows, and textures) done, we can now merge all of this into only one layer so we would only be working on one instead of applying the same effect over the rest of the layers which will eventually become a burden.  To merge all of the heart layers, let’s first turn off the visibility of the photograph layer, then right click on any of the layers comprising the heart then choose Merge Visible Layers then choose Expanded as Necessary.  This will then compress all of the heart layers into a single layer which would be very handy for our proceeding steps. Merging Visible Layers  
Read more
  • 0
  • 0
  • 8142

article-image-photo-compositing-gimp-part-1
Packt
07 Dec 2009
7 min read
Save for later

Photo Compositing with The GIMP: Part 1

Packt
07 Dec 2009
7 min read
Basing from my previous GIMP article titled Creating Pseudo-3D Imagery with GIMP, you learned how to do some basic selection manipulation, gradient application, faking Depth of Field, etc.  In line with that, I’m following it with a new article very much related to the concepts discussed therein but we’ll raise the bar a bit by having a glimpse on compositing, where we’ll use an existing image or photograph and later add in our 2-dimensional element seamlessly with the said picture. So if you haven’t read yet “Creating Pseudo-3D Imagery with GIMP”, I highly suggest you do so since almost all major concepts we’ll tackle here are based off of that article.  But if you have an idea on how to do the implied concepts here, then you’re good to go. If you have been following my advices lately, this might feel cliché to you, but you can’t blame me if I say “Always plan what you have to do!”, right? There you go, another useful and tad overused advice. Just to give you an overview, this article you are about to spend some time on will teach you basically how to: 1) add 2-dimensional elements to photos or just any other image you wish to, 2) apply effects to better enhance the composition, 3) plan out your scenes well However, this guide doesn’t teach you how to pick the right color combination nor does it help you how to shoot great photographs, but hopefully though, at the end of your reading, you’ll soon be able to apply the concepts with no hassle and get comfortable with it each time you do. Some of you might be a bit daunted by the title alone of this article, especially those of you most inclined with specialized compositing software, but as much as I would want to make use of those applications, I’m much more comfortable exploring what GIMP is capable of, not only as a simple drawing application but as a minor compositing app as well.  The concepts that I present here though are just basic representations of what compositing actually is.  And in this context, we’ll only be focusing on still images as reference and output all throughout this article.  If you wanted however to do compositing on series of images, animation, or movie, I highly suggest GIMP’s 3D partner – Blender. Ok, promotion set aside, let’s head back to the topic at hand. To give you an idea (because I believe [and I’m positive you do too] that pictures speak louder than words), here’s what we should be having by the end of this article, probably not exactly matching it but fairly close enough and I’ll try my best to be as guiding as possible. So let’s hop on! Heart and Sphere Composited with GIMP Compose, Compose, Compose! Yup, you read it thrice, I did too, don’t worry.  So what’s the fuss about composing anyway? The answer is pretty straightforward, though. Just like how a song is written through a composition, a photo/image is almost the same thing.  Without the proper composition, your image would never give life.  By composition, I mean a proper mix of colors, framing, lighting, etc.  This is one of the hardest obstacles any artist or photographer might face.  It will either ruin a majestic idea or it will turn your doodle into a wonderful creation you could almost hear the melody of your lines rhythm through your senses (wow, that was almost a mouthful!). Whichever tool you’re comfortable using, it really doesn’t differ a lot as compared to how you could easily interpret your ideas into something much more fruitful than worrying how to work your way around. That’s probably one reason I stuck into using GIMP, not only am I confident it can deliver anything I could 2-dimensionally think of but more importantly I am comfortable using it, which is a very important thing regarding design in my opinion. Just like how I wrote this article, composition comes into play (or you might already have doubted me already?).  Without the drafts and planning I made, I don’t believe I could even finish writing a paragraph of this one. To start off the process, we’ll use one photograph I shot just for this article (in an attempt to recreate the first image I showed you). Or if you don’t want to follow this article thoroughly, you can grab a sample photo from Google Images or from Stock Exchange (www.sxc.hu), just be sure to credit the owner though or whatever conditions or licenses the image has. Photo to work on Photo Enhancement Honestly, the photo we have is already decent enough to work with, but let’s just try making it better so we won’t have to go and adjust it later on. First, let’s open our image and do some primary color correction to it, just in case you’re the type who thinks “something has got to be better, always”.  Go ahead and fire up our tool of choice (GIMP in this case) and open the image (as you can see below). Opening the image in GIMP   With our photo active in our canvas and the layer it is on (which is the only layer that you see in the Layer Window by default), right click on the image, select Color, then choose Levels. Adjusting the image’s color levels is one good way to fix some color cast problems and to edit the color range of your colors non-destructively (extreme cases excluded), another great tool is using the Curves Tool to manipulate your image the same way that you do with Levels. But again, for the sake of this tutorial, we’ll use the levels tool since it’s much easier and faster to edit. You can see a screenshot below of the Levels Tool that we’ll be using in awhile. Levels Tool One nifty tool we can use under our Levels Tool is the Auto function which (you guessed it right again!), automates the color adjustment on our image based on the histogram reading and graph analysis of GIMP. Oftentimes, it makes the task easier for you but it might also ruin your image.  Nothing beats your visual judgment still so if you’re not contented with what the Auto Leveling gives you, go on and move the sliders that you see in the window.  Normally, I only adjust the Value data of the image to correct it’s overall brightness and contrast without altering the overall color mood of the photo.  But if in case you weren’t lucky enough to set your color balance settings on your camera the moment you shot the photo or if you felt the image you’re seeing infront of you is color casted too much, you can freely choose the other color channels (Red, Green, and Blue respectively) from the drop-down menu. You can see a screenshot below on how I adjusted the photo we currently loaded. Value Level Adjustment   RGB Color Level Choices That’s basically all that we need to do to enhance our photo (or you could go ahead and repeat the process a few more times to get the appropriate feel you wanted). If you wanted a safer way of editing (just in case you might run out of undo steps), duplicate your base layer that holds your image and work on the duplicate layer instead of the original one, then you can just switch the visibility on and off to see the changes you’ve made so far.
Read more
  • 0
  • 0
  • 5663

article-image-dynamic-menus-wordpress
Packt
07 Dec 2009
5 min read
Save for later

Dynamic Menus in WordPress

Packt
07 Dec 2009
5 min read
This is the nice thing about WordPress—it's all "dynamic". Once you install WordPress and design a great theme for it, anyone with the right level of administrative capability can log into the Administration Panel and add, edit, or delete content and menu items. But generally, when people ask for "dynamic menus", what they really want are those appearing and disappearing drop-down menus which, I believe, they like because it quickly gives a site a very "busy" feel. I must add my own disclaimer—I don't like dropdowns. Before you get on to my case, I will say it's not that they're "wrong" or "bad"; they just don't meet my own aesthetic standards and I personally find them non-user friendly. I'd prefer to see a menu system that, if subsections are required, displays them somewhere consistently on the page, either by having a vertical navigation expand to display subsections underneath, or showing additional subjections in a set location on the page if a horizontal menu is used. I like to be able to look around and say, "OK, I'm in the New Items | Cool Drink section and I can also check out Red Dinksand Retro Dinks within this section". Having to constantly go back up to the menu and drop-down the options to remind myself of what's available and what my next move might be, is annoying. Still haven't convinced you not to use drop-downs? OK, read on. Drop-down menus So you're going to use dropdowns. Again it's not "wrong"; however, I would strongly caution you to help your client take a look at their target users before implementing them. If there's a good chance that most users are going to use the latest browsers that support the current JavaScript, CSS, and Flash standards, and everyone has great mobility and is "mouse-ready", then there's really no problem in going for it. If it becomes apparent that any percentage of the site's target users will be using older browsers or have disabilities that prevent them from using a mouse and will limit them to tabbing through content, you must consider not using drop-down menus. I was especially negative about drop-down menus as, until recently, they required bulky JavaScripting or the use of Flash, which does not make clean, semantic, and SEO-friendly (or accessible) XHTML. Enter the Suckerfish method developed by Patrick Griffiths and Dan Webb. This method is wonderful because it takes valid, semantically accurate, unordered lists (WordPress' favorite!), and using almost pure CSS, creates dropdowns. The drop-down menus are not tab accessible, but they will simply display as a single, clear unordered list to older browsers that don't support the required CSS. IE6, as per usual, poses a problem or two for us, so there is some minimal DOM JavaScripting needed to compensate and achieve the correct effect in that browser. If you haven't heard of or worked with the Suckerfish method, I'm going to recommend you to go online (right now!) and read Dan and Patrick's article in detail (http://alistapart.com/articles/dropdowns). More recently, Patrick and Dan have revisited this method with "Son-of-a-Suckerfish", which offers multiple levels and an even further pared down DOM JavaScript. Check it out at http://www.htmldog.com/articles/suckerfish/dropdowns/. I also suggest you play around with the sample code provided in these articles so that you understand exactly how it works. Go on, and read it. When you get back, I'll review how to apply this method to your WordPress theme. DIY SuckerFish menus in WordPress All done? Great! As you can see, the essential part of this effect is getting your menu items to show up as unordered lists with sub unordered lists. Once you do that, the rest of the magic can be easily handled by finessing the CSS that Patrick and Dan suggest into your theme's CSS and placing the DOM script in your theme's header tag(s), in your header.php and/or index.php template files. Seriously, that's it! The really good news is that WordPress already outputs your content's pages and their subpages using unordered lists. Right-click on the page links in Firefox to View Selected Source and check that the DOM inspector shows us that the menu is, in fact, being displayed using an unordered list. Now you can go into your WordPress Administration panel and add as many pages and subpages as you'd like (Administration | Page | Add New). You'll use the Page Parent tab on the right to assign your subpages to their parent. If you installed the pageMash plugin, it's even easier! You can drag-and-drop your created pages into any configuration you'd like. Just be sure to hit the Update button when you're done. Once you've added subpages to a page, you'll be able to use the DOM Source of Selection viewer to see that your menu is displayed with unordered lists and sublists.
Read more
  • 0
  • 0
  • 3630

article-image-seasonal-ebook-offer-45
Packt
04 Dec 2009
1 min read
Save for later

Seasonal eBook Offer: Up to 45% off

Packt
04 Dec 2009
1 min read
Packt eBooks are an immediate and cost effective way of receiving one of our books and are a complete electronic version of the print edition.You will be delighted to know that now you can get 30% off on any ebook of your choice, and if you buy 2 or more ebooks, you get 45% off.
Read more
  • 0
  • 0
  • 1379
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at €18.99/month. Cancel anytime
article-image-blocking-common-attacks-using-modsecurity-25-part-1
Packt
01 Dec 2009
11 min read
Save for later

Blocking Common Attacks using ModSecurity 2.5: Part 1

Packt
01 Dec 2009
11 min read
Web applications can be attacked from a number of different angles, which is what makes defending against them so difficult. Here are just a few examples of where things can go wrong to allow a vulnerability to be exploited: The web server process serving requests can be vulnerable to exploits. Even servers such as Apache, that have a good security track record, can still suffer from security problems - it's just a part of the game that has to be accepted. The web application itself is of course a major source of problems. Originally, HTML documents were meant to be just that - documents. Over time, and especially in the last few years, they have evolved to also include code, such as client-side JavaScript. This can lead to security problems. A parallel can be drawn to Microsoft Office, which in earlier versions was plagued by security problems in its macro programming language. This, too, was caused by documents and executable code being combined in the same file. Supporting modules, such as mod_php which is used to run PHP scripts, can be subject to their own security vulnerabilities. Backend database servers, and the way that the web application interacts with them, can be a source of problems ranging from disclosure of confidential information to loss of data. HTTP fingerprinting Only amateur attackers blindly try different exploits against a server without having any idea beforehand whether they will work or not. More sophisticated adversaries will map out your network and system to find out as much information as possible about the architecture of your network and what software is running on your machines. An attacker looking to break in via a web server will try to find one he knows he can exploit, and this is where a method known as HTTP fingerprinting comes into play. We are all familiar with fingerprinting in everyday life - the practice of taking a print of the unique pattern of a person's finger to be able to identify him or her - for purposes such as identifying a criminal or opening the access door to a biosafety laboratory. HTTP fingerprinting works in a similar manner by examining the unique characteristics of how a web server responds when probed and constructing a fingerprint from the gathered information. This fingerprint is then compared to a database of fingerprints for known web servers to determine what server name and version is running on the target system. More specifically, HTTP fingerprinting works by identifying subtle differences in the way web servers handle requests - a differently formatted error page here, a slightly unusual response header there - to build a unique profile of a server that allows its name and version number to be identified. Depending on which viewpoint you take, this can be useful to a network administrator to identify which web servers are running on a network (and which might be vulnerable to attack and need to be upgraded), or it can be useful to an attacker since it will allow him to pinpoint vulnerable servers. We will be focusing on two fingerprinting tools: httprint One of the original tools - the current version is 0.321 from 2005, so it hasn't been updated with new signatures in a while. Runs on Linux, Windows, Mac OS X, and FreeBSD. httprecon This is a newer tool which was first released in 2007. It is still in active development. Runs on Windows. Let's first run httprecon against a standard Apache 2.2 server: And now let's run httprint against the same server and see what happens: As we can see, both tools correctly guess that the server is running Apache. They get the minor version number wrong, but both tell us that the major version is Apache 2.x. Try it against your own server! You can download httprint at http://www.net-square.com/httprint/ and httprecon at http://www.computec.ch/projekte/httprecon/. Tip If you get the error message Fingerprinting Error: Host/URL not found when running httprint, then try specifying the IP address of the server instead of the hostname. The fact that both tools are able to identify the server should come as no surprise as this was a standard Apache server with no attempts made to disguise it. In the following sections, we will be looking at how fingerprinting tools distinguish different web servers and see if we are able to fool them into thinking the server is running a different brand of web server software. How HTTP fingerprinting works There are many ways a fingerprinting tool can deduce which type and version of web server is running on a system. Let's take a look at some of the most common ones. Server banner The server banner is the string returned by the server in the Server response header (for example: Apache/1.3.3 (Unix) (Red Hat/Linux)). This banner can be changed by using the ModSecurity directive SecServerSignature. Here is what to do to change the banner: # Change the server banner to MyServer 1.0ServerTokens FullSecServerSignature "MyServer 1.0" Response header The HTTP response header contains a number of fields that are shared by most web servers, such as Server, Date, Accept-Ranges, Content-Length, and Content-Type. The order in which these fields appear can give a clue as to which web server type and version is serving the response. There can also be other subtle differences - the Netscape Enterprise Server, for example, prints its headers as Last-modified and Accept-ranges, with a lowercase letter in the second word, whereas Apache and Internet Information Server print the same headers as Last-Modified and Accept-Ranges. HTTP protocol responses An other way to gain information on a web server is to issue a non-standard or unusual HTTP request and observe the response that is sent back by the server. Issuing an HTTP DELETE request The HTTP DELETE command is meant to be used to delete a document from a server. Of course, all servers require that a user is authenticated before this happens, so a DELETE command from an unauthorized user will result in an error message - the question is just which error message exactly, and what HTTP error number will the server be using for the response page? Here is a DELETE request issued to our Apache server: $ nc bytelayer.com 80DELETE / HTTP/1.0HTTP/1.1 405 Method Not AllowedDate: Mon, 27 Apr 2009 09:10:49 GMTServer: Apache/2.2.8 (Fedora) mod_jk/1.2.27 DAV/2Allow: GET,HEAD,POST,OPTIONS,TRACEContent-Length: 303Connection: closeContent-Type: text/html; charset=iso-8859-1<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"><html><head><title>405 Method Not Allowed</title></head><body><h1>Method Not Allowed</h1><p>The requested method DELETE is not allowed for the URL /index.html.</p><hr><address>Apache/2.2.8 (Fedora) mod_jk/1.2.27 DAV/2 Server at www.bytelayer.com Port 80</address></body></html> As we can see, the server returned a 405 - Method Not Allowed error. The error message accompanying this response in the response body is given as The requested method DELETE is not allowed for the URL/index.html. Now compare this with the following response, obtained by issuing the same request to a server at www.iis.net: $ nc www.iis.net 80DELETE / HTTP/1.0HTTP/1.1 405 Method Not AllowedAllow: GET, HEAD, OPTIONS, TRACEContent-Type: text/htmlServer: Microsoft-IIS/7.0Set-Cookie: CSAnonymous=LmrCfhzHyQEkAAAANWY0NWY1NzgtMjE2NC00NDJjLWJlYzYtNTc4ODg0OWY5OGQz0; domain=iis.net; expires=Mon, 27-Apr-2009 09:42:35GMT; path=/; HttpOnlyX-Powered-By: ASP.NETDate: Mon, 27 Apr 2009 09:22:34 GMTConnection: closeContent-Length: 1293<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html ><head><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/><title>405 - HTTP verb used to access this page is not allowed.</title><style type="text/css"><!--body{margin:0;font-size:.7em;font-family:Verdana, Arial, Helvetica,sans-serif;background:#EEEEEE;}fieldset{padding:0 15px 10px 15px;}h1{font-size:2.4em;margin:0;color:#FFF;}h2{font-size:1.7em;margin:0;color:#CC0000;}h3{font-size:1.2em;margin:10px 0 0 0;color:#000000;}#header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;fontfamily:"trebuchet MS", Verdana, sans-serif;color:#FFF;background-color:#555555;}#content{margin:0 0 0 2%;position:relative;}.content-container{background:#FFF;width:96%;margin-top:8px;padding:10px;position:relative;}--></style>< /head><body><div id="header"><h1>Server Error</h1></div><div id="content"><div class="content-container"><fieldset> <h2>405 - HTTP verb used to access this page is not allowed.</h2> <h3>The page you are looking for cannot be displayed because aninvalid method (HTTP verb) was used to attempt access.</h3> </fieldset></div></div></body></html> The site www.iis.net is Microsoft's official site for its web server platform Internet Information Services, and the Server response header indicates that it is indeed running IIS-7.0. (We have of course already seen that it is a trivial operation in most cases to fake this header, but given the fact that it's Microsoft's official IIS site we can be pretty sure that they are indeed running their own web server software.) The response generated from IIS carries the same HTTP error code, 405; however there are many subtle differences in the way the response is generated. Here are just a few: IIS uses spaces in between method names in the comma separated list for the Allow field, whereas Apache does not The response header field order differs - for example, Apache has the Date field first, whereas IIS starts out with the Allow field IIS uses the error message The page you are looking for cannot be displayed because an invalid method (HTTP verb) was used to attempt access in the response body Bad HTTP version numbers A similar experiment can be performed by specifying a non-existent HTTP protocol version number in a request. Here is what happens on the Apache server when the request GET / HTTP/5.0 is issued: $ nc bytelayer.com 80GET / HTTP/5.0HTTP/1.1 400 Bad RequestDate: Mon, 27 Apr 2009 09:36:10 GMTServer: Apache/2.2.8 (Fedora) mod_jk/1.2.27 DAV/2Content-Length: 295Connection: closeContent-Type: text/html; charset=iso-8859-1<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"><html><head><title>400 Bad Request</title></head><body><h1>Bad Request</h1><p>Your browser sent a request that this server could notunderstand.<br /></p><hr><address>Apache/2.2.8 (Fedora) mod_jk/1.2.27 DAV/2 Server at www.bytelayer.com Port 80</address></body></html> There is no HTTP version 5.0, and there probably won't be for a long time, as the latest revision of the protocol carries version number 1.1. The Apache server responds with a 400 - Bad Request Error, and the accompanying error message in the response body is Your browser sent a request that this server could not understand. Now let's see what IIS does: $ nc www.iis.net 80GET / HTTP/5.0HTTP/1.1 400 Bad RequestContent-Type: text/html; charset=us-asciiServer: Microsoft-HTTPAPI/2.0Date: Mon, 27 Apr 2009 09:38:37 GMTConnection: closeContent-Length: 334<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd"><HTML><HEAD><TITLE>Bad Request</TITLE><META HTTP-EQUIV="Content-Type" Content="text/html; charset=usascii"></HEAD><BODY><h2>Bad Request - Invalid Hostname</h2><hr><p>HTTP Error 400. The request hostname is invalid.</p></BODY></HTML> We get the same error number, but the error message in the response body differs - this time it's HTTP Error 400. The request hostname is invalid. As HTTP 1.1 requires a Host header to be sent with requests, it is obvious that IIS assumes that any later protocol would also require this header to be sent, and the error message reflects this fact.
Read more
  • 0
  • 0
  • 5656

article-image-moodle-19-math-quizzes-part-3
Packt
01 Dec 2009
3 min read
Save for later

Moodle 1.9 Math Quizzes: Part 3

Packt
01 Dec 2009
3 min read
Using STACK My original problem was this: how can I ask my students to expand (x+4)(x-3) and have Moodle automatically mark my students' answers—hopefully with an answer equivalent to x2+x-12. Let's create that question now. Creating a STACK question Return to your course's front page and, from the course administration block, click on Questions to open the course question bank. Then, follow these steps: Click on the Create new question drop-down menu and choose Opaque: On the Add Opaque Question page, click on Manage Stack Questions: A new window (or tab, depending on your browser) is opened. On the Questions available from STACK question engine page, click on the New Question link: Give your question a name (suitable for you to be able to find it again and know what the question is when you do). Write your question in the Question Stem. You need to be careful with the format: math notation can be written in LaTeX (denoted, in my case, with single dollars). Note how I've specified a variable for the student's answer (#answer#). You can call this variable whatever you like, as long as you enclose it in #: Scroll down to the Update button immediately under the Question Note option and click on it: An Interaction Elements section is now inserted into the page. You will need to specify the answer in the Teacher's Answer row. Be careful with the format as it has to be a valid CAS expression (for example, 3x should be specified as 3*x). When you have filled in your answer, click on the Update button at the bottom of this section: We've asked the question and specified our answer. We now need to program STACK to understand whether or not the student's answer is correct. In the Potential Response Trees block, specify a name for the response and press the + button: The student's answer is stored in the variable answer. My answer needs to be specified in the TAns (teacher's answer box). As this is the correct answer, I can copy and paste from the Teacher's Answer in the Interaction Elements box. Notice that the Answer test is AlgEquiv (algebraic equivalents): Now, click on the Update button at the bottom of the Potential Response Trees section. A common mistake when expanding brackets is to forget to multiply out completely (typically submit x2-12 as the answer). Let's accommodate this now in the Potential Response Trees. Add another PR (potential response) by choosing to add 1 new potential response from the drop-down list and clicking the Add button: Populate the new potential response with the incorrect answer and some feedback. Remember to ensure that they aren't awarded a mark for getting the answer wrong: We now have two nodes in the Potential Response Trees that we need to link together. From the actual correct answer response (node No: 0), click on the Next PR drop-down in the false block and choose 1: Can you see how we are linking potential responses together to form a tree of nodes? Click on the Update button at the bottom of the Potential Responses section to save your changes. Scroll down to the bottom of the page, and click on the Save button: The page reloads, and if we have specified everything correctly, then we now have the opportunity to try our new question. Click on Try question: Try specifying different answers to see how Moodle responds. Make sure any feedback you specified is displayed correctly: When you have finished testing, click on the Finished button at the bottom of the page.
Read more
  • 0
  • 0
  • 2225

article-image-blocking-common-attacks-using-modsecurity-25-part-2
Packt
01 Dec 2009
11 min read
Save for later

Blocking Common Attacks using ModSecurity 2.5: Part 2

Packt
01 Dec 2009
11 min read
Cross-site scripting Cross-site scripting attacks occur when user input is not properly sanitized and ends up in pages sent back to users. This makes it possible for an attacker to include malicious scripts in a page by providing them as input to the page. The scripts will be no different than scripts included in pages by the website creators, and will thus have all the privileges of an ordinary script within the page—such as the ability to read cookie data and session IDs. In this article we will look in more detail on how to prevent attacks. The name "cross-site scripting" is actually rather poorly chosen—the name stems from the first such vulnerability that was discovered, which involved a malicious website using HTML framesets to load an external site inside a frame. The malicious site could then manipulate the loaded external site in various ways—for example, read form data, modify the site, and basically perform any scripting action that a script within the site itself could perform. Thus cross-site scripting, or XSS, was the name given to this kind of attack. The attacks described as XSS attacks have since shifted from malicious frame injection (a problem that was quickly patched by web browser developers) to the class of attacks that we see today involving unsanitized user input. The actual vulnerability referred to today might be better described as a "malicious script injection attack", though that doesn't give it quite as flashy an acronym as XSS. (And in case you're curious why the acronym is XSS and not CSS, the simple explanation is that although CSS was used as short for cross-site scripting in the beginning, it was changed to XSS because so many people were confusing it with the acronym used for Cascading Style Sheets, which is also CSS.) Cross-site scripting attacks can lead not only to cookie and session data being stolen, but also to malware being downloaded and executed and injection of arbitrary content into web pages. Cross-site scripting attacks can generally be divided into two categories: Reflected attacksThis kind of attack exploits cases where the web application takes data provided by the user and includes it without sanitization in output pages. The attack is called "reflected" because an attacker causes a user to provide a malicious script to a server in a request that is then reflected back to the user in returned pages, causing the script to execute. Stored attacksIn this type of XSS attack, the attacker is able to include his malicious payload into data that is permanently stored on the server and will be included without any HTML entity encoding to subsequent visitors to a page. Examples include storing malicious scripts in forum posts or user presentation pages. This type of XSS attack has the potential to be more damaging since it can affect every user who views a certain page. Preventing XSS attacks The most important measure you can take to prevent XSS attacks is to make sure that all user-supplied data that is output in your web pages is properly sanitized. This means replacing potentially unsafe characters, such as angled brackets (< and >) with their corresponding HTML-entity encoded versions—in this case &lt; and &gt;. Here is a list of characters that you should encode when present in user-supplied data that will later be included in web pages: Character HTML-encoded version < &lt; > &gt; ( &#40; ) &#41; # &#35; & &amp; " &quot; ' &#39; In PHP, you can use the htmlentities() function to achieve this. When encoded, the string <script> will be converted into &lt;script&gt;. This latter version will be displayed as <script> in the web browser, without being interpreted as the start of a script by the browser. In general, users should not be allowed to input any HTML markup tags if it can be avoided. If you do allow markup such as <a href="..."> to be input by users in blog comments, forum posts, and similar places then you should be aware that simply filtering out the <script> tag is not enough, as this simple example shows: <a href="http://www.google.com" onMouseOver="javascript:alert('XSS Exploit!')">Innocent link</a> This link will execute the JavaScript code contained within the onMouseOver attribute whenever the user hovers his mouse pointer over the link. You can see why even if the web application replaced <script> tags with their HTML-encoded version, an XSS exploit would still be possible by simply using onMouseOver or any of the other related events available, such as onClick or onMouseDown. I want to stress that properly sanitizing user input as just described is the most important step you can take to prevent XSS exploits from occurring. That said, if you want to add an additional line of defense by creating ModSecurity rules, here are some common XSS script fragments and regular expressions for blocking them: Script fragment Regular expression <script <script eval( evals*( onMouseOver onmouseover onMouseOut onmouseout onMouseDown onmousedown onMouseMove onmousemove onClick onclick onDblClick ondblclick onFocus onfocus PDF XSS protection You may have seen the ModSecurity directive SecPdfProtect mentioned, and wondered what it does. This directive exists to protect users from a particular class of cross-site scripting attack that affects users running a vulnerable version of the Adobe Acrobat PDF reader. A little background is required in order to understand what SecPdfProtect does and why it is necessary. In 2007, Stefano Di Paola and Giorgio Fedon discovered a vulnerability in Adobe Acrobat that allows attackers to insert JavaScript into requests, which is then executed by Acrobat in the context of the site hosting the PDF file. Sound confusing? Hang on, it will become clearer in a moment. The vulnerability was quickly fixed by Adobe in version 7.0.9 of Acrobat. However, there are still many users out there running old versions of the reader, which is why preventing this sort of attack is still an ongoing concern. The basic attack works like this: An attacker entices the victim to click a link to a PDF file hosted on www.example.com. Nothing unusual so far, except for the fact that the link looks like this: http://www.example.com/document.pdf#x=javascript:alert('XSS'); Surprisingly, vulnerable versions of Adobe Acrobat will execute the JavaScript in the above link. It doesn't even matter what you place before the equal sign, gibberish= will work just as well as x= in triggering the exploit. Since the PDF file is hosted on the domain www.example.com, the JavaScript will run as if it was a legitimate piece of script within a page on that domain. This can lead to all of the standard cross-site scripting attacks that we have seen examples of before. This diagram shows the chain of events that allows this exploit to function: The vulnerability does not exist if a user downloads the PDF file and then opens it from his local hard drive. ModSecurity solves the problem of this vulnerability by issuing a redirect for all PDF files. The aim is to convert any URLs like the following: http://www.example.com/document.pdf#x=javascript:alert('XSS'); into a redirected URL that has its own hash character: http://www.example.com/document.pdf#protection This will block any attacks attempting to exploit this vulnerability. The only problem with this approach is that it will generate an endless loop of redirects, as ModSecurity has no way of knowing what is the first request for the PDF file, and what is a request that has already been redirected. ModSecurity therefore uses a one-time token to keep track of redirect requests. All redirected requests get a token included in the new request string. The redirect link now looks like this: http://www.example.com/document.pdf?PDFTOKEN=XXXXX#protection ModSecurity keeps track of these tokens so that it knows which links are valid and should lead to the PDF file being served. Even if a token is not valid, the PDF file will still be available to the user, he will just have to download it to the hard drive. These are the directives used to configure PDF XSS protection in ModSecurity: SecPdfProtect On SecPdfProtectMethod TokenRedirection SecPdfProtectSecret "SecretString" SecPdfProtectTimeout 10 SecPdfProtectTokenName "token" The above configures PDF XSS protection, and uses the secret string SecretString to generate the one-time tokens. The last directive, SecPdfProtectTokenName, can be used to change the name of the token argument (the default is PDFTOKEN). This can be useful if you want to hide the fact that you are running ModSecurity, but unless you are really paranoid it won't be necessary to change this. The SecPdfProtectMethod can also be set to ForcedDownload, which will force users to download the PDF files instead of viewing them in the browser. This can be an inconvenience to users, so you would probably not want to enable this unless circumstances warrant (for example, if a new PDF vulnerability of the same class is discovered in the future). HttpOnly cookies to prevent XSS attacks One mechanism to mitigate the impact of XSS vulnerabilities is the HttpOnly flag for cookies. This extension to the cookie protocol was proposed by Microsoft (see http://msdn.microsoft.com/en-us/library/ms533046.aspx for a description), and is currently supported by the following browsers: Internet Explorer (IE6 SP1 and later) Firefox (2.0.0.5 and later) Google Chrome (all versions) Safari (3.0 and later) Opera (version 9.50 and later) HttpOnly cookies work by adding the HttpOnly flag to cookies that are returned by the server, which instructs the web browser that the cookie should only be used when sending HTTP requests to the server and should not be made available to client-side scripts via for example the document.cookie property. While this doesn't completely solve the problem of XSS attacks, it does mitigate those attacks where the aim is to steal valuable information from the user's cookies, such as for example session IDs. A cookie header with the HttpOnly flag set looks like this: Set-Cookie: SESSID=d31cd4f599c4b0fa4158c6fb; HttpOnly HttpOnly cookies need to be supported on the server-side for the clients to be able to take advantage of the extra protection afforded by them. Some web development platforms currently support HttpOnly cookies through the use of the appropriate configuration option. For example, PHP 5.2.0 and later allow HttpOnly cookies to be enabled for a page by using the following ini_set() call: <?php ini_set("session.cookie_httponly", 1); ?> Tomcat (a Java Servlet and JSP server) version 6.0.19 and later supports HttpOnly cookies, and they can be enabled by modifying a context's configuration so that it includes the useHttpOnly option, like so: <Context> <Manager useHttpOnly="true" /> </Context> In case you are using a web platform that doesn't support HttpOnly cookies, it is actually possible to use ModSecurity to add the flag to outgoing cookies. We will see how to do this now. Session identifiers Assuming we want to add the HttpOnly flag to session identifier cookies, we need to know which cookies are associated with session identifiers. The following table lists the name of the session identifier cookie for some of the most common languages: Language Session identifier cookie name PHP PHPSESSID JSP JSESSIONID ASP ASPSESSIONID ASP.NET ASP.NET_SessionId The table shows us that a good regular expression to identify session IDs would be (sessionid|sessid), which can be shortened to sess(ion)?id. The web programming language you are using might use another name for the session cookie. In that case, you can always find out what it is by looking at the headers returned by the server: echo -e "GET / HTTP/1.1nHost:yourserver.comnn"|nc yourserver.com 80|head Look for a line similar to: Set-Cookie: JSESSIONID=4EFA463BFB5508FFA0A3790303DE0EA5; Path=/ This is the session cookie—in this case the name of it is JESSIONID, since the server is running Tomcat and the JSP web application language. The following rules are used to add the HttpOnly flag to session cookies: # # Add HttpOnly flag to session cookies # SecRule RESPONSE_HEADERS:Set-Cookie "!(?i:HttpOnly)" "phase:3,chain,pass" SecRule MATCHED_VAR "(?i:sess(ion)?id)" "setenv:session_ cookie=%{MATCHED_VAR}" Header set Set-Cookie "%{SESSION_COOKIE}e; HttpOnly" env=session_ cookie We are putting the rule chain in phase 3—RESPONSE_HEADERS, since we want to inspect the response headers for the presence of a Set-Cookie header. We are looking for those Set-Cookie headers that do not contain an HttpOnly flag. The (?i: ) parentheses are a regular expression construct known as a mode-modified span. This tells the regular expression engine to ignore the case of the HttpOnly string when attempting to match. Using the t:lowercase transform would have been more complicated, as we will be using the matched variable in the next rule, and we don't want the case of the variable modified when we set the environment variable.
Read more
  • 0
  • 0
  • 6228

article-image-blocking-common-attacks-using-modsecurity-25-part-3
Packt
01 Dec 2009
12 min read
Save for later

Blocking Common Attacks using ModSecurity 2.5: Part 3

Packt
01 Dec 2009
12 min read
Source code revelation Normally, requesting a file with a .php extension will cause mod_php to execute the PHP code contained within the file and then return the resulting web page to the user. If the web server is misconfigured (for example if mod_php is not loaded) then the .php file will be sent by the server without interpretation, and this can be a security problem. If the source code contains credentials used to connect to an SQL database then that opens up an avenue for attack, and of course the source code being available will allow a potential attacker to scrutinize the code for vulnerabilities. Preventing source code revelation is easy. With response body access on in ModSecurity, simply add a rule to detect the opening PHP tag: Prevent PHP source code from being disclosed SecRule RESPONSE_BODY "<?" "deny,msg:'PHP source code disclosure blocked'" Preventing Perl and JSP source code from being disclosed works in a similar manner: # Prevent Perl source code from being disclosed SecRule RESPONSE_BODY "#!/usr/bin/perl" "deny,msg:'Perl source code disclosure blocked'" # Prevent JSP source code from being disclosed SecRule RESPONSE_BODY "<%" "deny,msg:'JSP source code disclosure blocked'" Directory traversal attacks Normally, all web servers should be configured to reject attempts to access any document that is not under the web server's root directory. For example, if your web server root is /home/www, then attempting to retrieve /home/joan/.bashrc should not be possible since this file is not located under the /home/www web server root. The obvious attempt to access the /home/joan directory is, of course, easy for the web server to block, however there is a more subtle way to access this directory which still allows the path to start with /home/www, and that is to make use of the .. symbolic directory link which links to the parent directory in any given directory. Even though most web servers are hardened against this sort of attack, web applications that accept input from users may still not be checking it properly, potentially allowing users to get access to files they shouldn't be able to view via simple directory traversal attacks. This alone is reason to implement protection against this sort of attack using ModSecurity rules. Furthermore, keeping with the principle of Defense in Depth, having multiple protections against this vulnerability can be beneficial in case the web server should contain a flaw that allows this kind of attack in certain circumstances. There is more than one way to validly represent the .. link to the parent directory. URL encoding of .. yields % 2e% 2e, and adding the final slash at the end we end up with % 2e% 2e% 2f(please ignore the space). Here, then is a list of what needs to be blocked: ../ ..% 2f .% 2e/ %  2e%  2e% 2f % 2e% 2e/ % 2e./ Fortunately, we can use the ModSecurity transformation t:urlDecode. This function does all the URL decoding for us, and will allow us to ignore the percent-encoded values, and thus only one rule is needed to block these attacks: SecRule REQUEST_URI "../" "t:urlDecode,deny" Blog spam The rise of weblogs, or blogs, as a new way to present information, share thoughts, and keep an online journal has made way for a new phenomenon: blog comments designed to advertise a product or drive traffic to a website. Blog spam isn't a security problem per se, but it can be annoying and cost a lot of time when you have to manually remove spam comments (or delete them from the approval queue, if comments have to be approved before being posted on the blog). Blog spam can be mitigated by collecting a list of the most common spam phrases, and using the ability of ModSecurity to scan POST data. Any attempted blog comment that contains one of the offending phrases can then be blocked. From both a performance and maintainability perspective, using the @pmFromFile operator is the best choice when dealing with large word lists such as spam phrases. To create the list of phrases to be blocked, simply insert them into a text file, for example, /usr/local/spamlist.txt: viagra v1agra auto insurance rx medications cheap medications ... Then create ModSecurity rules to block those phrases when they are used in locations such as the page that creates new blog comments: # # Prevent blog spam by checking comment against known spam # phrases in file /usr/local/spamlist.txt # <Location /blog/comment.php> SecRule ARGS "@pmFromFile /usr/local/spamlist.txt" "t: lowercase,deny,msg:'Blog spam blocked'" </Location> Keep in mind that the spam list file can contain whole sentences—not just single words—so be sure to take advantage of that fact when creating the list of known spam phrases. SQL injection SQL injection attacks can occur if an attacker is able to supply data to a web application that is then used in unsanitized form in an SQL query. This can cause the SQL query to do completely different things than intended by the developers of the web application. Consider an SQL query like this: SELECT * FROM user WHERE username = '%s' AND password = '%s'; The flaw here is that if someone can provide a password that looks like ' OR '1'='1, then the query, with username and password inserted, will become: SELECT * FROM user WHERE username = 'anyuser' AND password = '' OR '1'='1'; This query will return all users in the results table, since the OR '1'='1' part at the end of the statement will make the entire statement true no matter what username and password is provided. Standard injection attempts Let's take a look at some of the most common ways SQL injection attacks are performed. Retrieving data from multiple tables with UNION An SQL UNION statement can be used to retrieve data from two separate tables. If there is one table named cooking_recipes and another table named user_credentials, then the following SQL statement will retrieve data from both tables: SELECT dish_name FROM recipe UNION SELECT username, password FROM user_credentials; It's easy to see how the UNION statement can allow an attacker to retrieve data from other tables in the database if he manages to sneak it into a query. A similar SQL statement is UNION ALL, which works almost the same way as UNION—the only difference is that UNION ALL will not eliminate any duplicate rows returned in the result. Multiple queries in one call If the SQL engine allows multiple statements in a single SQL query then seemingly harmless statements such as the following can present a problem: SELECT * FROM products WHERE id = %d; If an attacker is able to provide an ID parameter of 1; DROP TABLE products;, then the statement suddenly becomes: SELECT * FROM products WHERE id = 1; DROP TABLE products; When the SQL engine executes this, it will first perform the expected SELECT query, and then the DROP TABLE products statement, which will cause the products table to be deleted. Reading arbitrary files MySQL can be used to read data from arbitrary files on the system. This is done by using the LOAD_FILE() function: SELECT LOAD_FILE("/etc/passwd"); This command returns the contents of the file /etc/passwd. This works for any file to which the MySQL process has read access. Writing data to files MySQL also supports the command INTO OUTFILE which can be used to write data into files. This attack illustrates how dangerous it can be to include user-supplied data in SQL commands, since with the proper syntax, an SQL command can not only affect the database, but also the underlying file system. This simple example shows how to use MySQL to write the string some data into the file test.txt: mysql> SELECT "some data" INTO OUTFILE "test.txt"; Preventing SQL injection attacks There are three important steps you need to take to prevent SQL injection attacks: Use SQL prepared statements. Sanitize user data. Use ModSecurity to block SQL injection code supplied to web applications. These are in order of importance, so the most important consideration should always be to make sure that any code querying SQL databases that relies on user input should use prepared statements. A prepared statement looks as follows: SELECT * FROM books WHERE isbn = ? AND num_copies < ?; This allows the SQL engine to replace the question marks with the actual data. Since the SQL engine knows exactly what is data and what SQL syntax, this prevents SQL injection from taking place. The advantages of using prepared statements are twofold: They effectively prevent SQL injection. They speed up execution time, since the SQL engine can compile the statement once, and use the pre-compiled statement on all subsequent query invocations. So not only will using prepared statements make your code more secure—it will also make it quicker. The second step is to make sure that any user data used in SQL queries is sanitized. Any unsafe characters such as single quotes should be escaped. If you are using PHP, the function mysql_real_escape_string() will do this for you. Finally, let's take a look at strings that ModSecurity can help block to prevent SQL injection attacks. What to block The following table lists common SQL commands that you should consider blocking, together with a suggested regular expression for blocking. The regular expressions are in lowercase and therefore assume that the t:lowercase transformation function is used. SQL code Regular expression UNION SELECT unions+select UNION ALL SELECT unions+alls+select INTO OUTFILE intos+outfile DROP TABLE drops+table ALTER TABLE alters+table LOAD_FILE load_file SELECT * selects+* For example, a rule to detect attempts to write data into files using INTO OUTFILE looks as follows: SecRule ARGS "intos+outfile" "t:lowercase,deny,msg: 'SQL Injection'" The s+ regular expression syntax allows for detection of an arbitrary number of whitespace characters. This will detect evasion attempts such as INTO%20%20OUTFILE where multiple spaces are used between the SQL command words. Website defacement We've all seen the news stories: "Large Company X was yesterday hacked and their homepage was replaced with an obscene message". This sort of thing is an everyday occurrence on the Internet. After the company SCO initiated a lawsuit against Linux vendors citing copyright violations in the Linux source code, the SCO corporate website was hacked and an image was altered to read WE OWN ALL YOUR CODE—pay us all your money. The hack was subtle enough that the casual visitor to the SCO site would likely not be able to tell that this was not the official version of the homepage: The above image shows what the SCO homepage looked like after being defaced—quite subtle, don't you think? Preventing website defacement is important for a business for several reasons: Potential customers will turn away when they see the hacked site There will be an obvious loss of revenue if the site is used for any sort of e-commerce sales Bad publicity will tarnish the company's reputation Defacement of a site will of course depend on a vulnerability being successfully exploited. The measures we will look at here are aimed to detect that a defacement has taken place, so that the real site can be restored as quickly as possible. Detection of website defacement is usually done by looking for a specific token in the outgoing web pages. This token has been placed within the pages in advance specifically so that it may be used to detect defacement—if the token isn't there then the site has likely been defaced. This can be sufficient, but it can also allow the attacker to insert the same token into his defaced page, defeating the detection mechanism. Therefore, we will go one better and create a defacement detection technology that will be difficult for the hacker to get around. To create a dynamic token, we will be using the visitor's IP address. The reason we use the IP address instead of the hostname is that a reverse lookup may not always be possible, whereas the IP address will always be available. The following example code in JSP illustrates how the token is calculated and inserted into the page. <%@ page import="java.security.*" %> <% String tokenPlaintext = request.getRemoteAddr(); String tokenHashed = ""; String hexByte = ""; // Hash the IP address MessageDigest md5 = MessageDigest.getInstance("MD5"); md5.update(tokenPlaintext.getBytes()); byte[] digest = md5.digest(); for (int i = 0; i < digest.length; i++) { hexByte = Integer.toHexString(0xFF & digest[i]); if (hexByte.length() < 2) { hexByte = "0" + hexByte; } tokenHashed += hexByte; } // Write MD5 sum token to HTML document out.println(String.format("<span style='color: white'>%s</span>", tokenHashed)); %>   Assuming the background of the page is white, the <span style="color: white"> markup will ensure it is not visible to website viewers. Now for the ModSecurity rules to handle the defacement detection. We need to look at outgoing pages and make sure that they include the appropriate token. Since the token will be different for different users, we need to calculate the same MD5 sum token in our ModSecurity rule and make sure that this token is included in the output. If not, we block the page from being sent and sound the alert by sending an email message to the website administrator. # # Detect and block outgoing pages not containing our token # SecRule REMOTE_ADDR ".*" "phase:4,deny,chain,t:md5,t:hexEncode, exec:/usr/bin/emailadmin.sh" SecRule RESPONSE_BODY "!@contains %{MATCHED_VAR}" We are placing the rule in phase 4 since this is required when we want to inspect the response body. The exec action is used to send an email to the website administrator to let him know of the website defacement.
Read more
  • 0
  • 1
  • 11735
article-image-drag-and-drop-yui-part-1
Packt
30 Nov 2009
7 min read
Save for later

Drag-and-Drop with the YUI: Part-1

Packt
30 Nov 2009
7 min read
Dynamic Drag-and-Drop without the Hassle Like most of the other library components, when creating your own drag-and-drop elements, there are a range of different options available to you that allow you to tailor those objects to your requirements. These properties, like those of most other library components, can be set using an object literal supplied with the constructor, but in most cases even this is not required. The most challenging aspects of any drag-and-drop scenario in your web applications are going to center around the design of your specific implementation rather than in getting drag-and-drop to work in the first place. This utility is yet another example of the huge benefits the YUI can provide in reducing the amount of coding and troubleshooting that you need to concern yourself with. The Different Components of Drag-and-Drop In addition to the configurable properties used in your object literal, you also have several constructors that can be used to enable drag-and-drop. The first constructor YAHOO.util.DD allows for drag-and-drop at its most basic level. The supplied element will be transformed into an object that can be dragged around the page. The mechanics of drag-and-drop result in a burden of fairly high processing. The library has to keep track of the mouse pointer whilst it is moving, the draggable object needs to be repositioned, and different events are almost continually firing while the drag is taking place. In order to minimize the amount of information that needs to be processed, especially when the draggable object is fairly large, you can make use of a proxy element that will track across the page with the mouse pointer. When the proxy element reaches its final destination, it disappears and is replaced by the actual element. If a proxy element is required, we can use the YAHOO.util.DDProxy constructor instead of the basic constructor. As the proxy element is just an empty <div>, it's much easier to track and can even be shared between different drag objects on the page, reducing the overall processing that's required. Personally I think the default appearance of the proxy element is perfectly adequate, however you can also create your own custom elements to use as a proxy. The figure below shows the default proxy-element appearance: Design Considerations When working with DragDrop implementations, it is useful to consider the following aspects of the design: Can any part of the drag object be clicked on to initiate the drag, or should a drag handle be defined? Can the object be dropped on to any part of the page or should a specific drop target be defined? Should anything occur whilst the object is being dragged? Should anything occur when the item is dropped on a non-valid target? Should anything occur when the object is dropped on to a valid target? Events Events are an integral aspect of many DragDrop situations. Sometimes, however, being able to move something around the screen is the only behavior that's required, but generally you'll want something to happen either while the object is being dragged, or when it is dropped. The YAHOO.util.DragDrop utility provides a series of custom events which allow you to hook into and respond to events such as startDrag, endDrag, onDrag, onDragDrop, and onInvalidDrop. Valid targets also expose events of their own including onDragEnter, onDragOut, and onDragOver. We will be looking at a number of these events during the example that follows. Allowing Your Visitors to Drag-and-Drop The Drag-and-Drop utility uses tried and tested DHTML techniques, as well as some innovative new features, to allow you to easily create objects that can be dragged and then dropped. All that you need to do to make an element on your page dragable is to create a new instance of the YAHOO.util.DD class and feed in the id or element reference of the element that drag is to be enabled for. DragDrop Classes The base class of the Drag-and-Drop utility is YAHOO.util. DragDrop, but you'll use one of its extending subclasses, like YAHOO.util.DD, most of the time. This subclass inherits all of the properties and methods of the base class and even adds a few of its own, so it's more than capable of handling most of your drag-and-drop requirements. The YAHOO.util.DD class also has its own subclasses to deal with additional drag-and-drop requirements for different situations. The subclasses are YAHOO.util.DDProxy and YAHOO.widget.SliderThumb. As you can see, the Drag-and-Drop utility provides some of the basic functionality of another of the controls found in the YUI, the Slider Control (which we will look at in more detail towards the end of this article). Let's examine the DDProxy class, as that is relevant specifically to the Drag-and-Drop utility. Creating a proxy object that tracks with the cursor when a drag object is being dragged instead of allowing the actual drag object to track can prevent problems that arise with large drag objects not tracking properly or obscuring other content on the page. The proxy object is a small, empty object that represents the drag object and shows only its borders. The proxy object is created on the mouseDown event of the drag object and the actual drag object does not move to its new position until the mouseUp event is fired. Using a proxy object is both visually appealing and better overall for all but the simplest of implementations performance wise. The Constructor The constructor for an instance of the DragDrop object can also take a second or third argument when you are instantiating objects for dragging. The second argument, which is optional, specifies the group to which the element being dragged belongs. This refers to interaction groups—the object being dragged can only interact with and fire events with other elements in its interaction group. The third argument, which is also optional, can be used to supply a configuration object, the members of which hold additional optional configuration properties that can easily be accessed and set. Every object instantiated with the drag-and-drop constructor is a member of one or more interaction group(s), even if the second argument is not passed. When the argument is not supplied, the object will simply belong to the 'default' group instead. There is no limit as to how many groups an object can belong to. The API provides just two methods that relate to group access. .addToGroup() is used to add the object to more than one group, so the first group membership is defined with the constructor and subsequent groups with the .addToGroup() method. To remove an object from a group, just call the .removeFromGroup() method. Target Practice There is no doubt that drag-and-drop adds a hands-on, fun element to surfing the net that is way more engaging than simple point-and-click scenarios, and there are many serious applications of this behavior too. But dragging is only half of the action; without assigned drop targets, the usefulness of being able to drag elements on the page around at leisure is almost wasted. Drop targets have a class of their own in the Drag-and-Drop utility. Which extends the YAHOO.util.DragDrop base class to cater for the creation of drag elements that aren't actually dragable and this is the defining attribute of a drop target. The constructor is exactly the same as for the DD and Proxy classes with regard to the arguments passed, but YAHOO.util.DDTarget is used instead. The Target class has no methods or properties of its own, but it inherits all of the same methods and properties as the other two classes, including all of the events.
Read more
  • 0
  • 0
  • 4507

article-image-introducing-business-activity-monitoring
Packt
30 Nov 2009
7 min read
Save for later

Introducing Business Activity Monitoring

Packt
30 Nov 2009
7 min read
Introducing Business Activity Monitoring Typically, an organization's processes span multiple systems, channels, applications, departments, and external partners. In this case, how do we monitor such processes? What is the current state of the organizational processes? What is the benchmark for poorly-performing processes and exceptional processes? Most of the time, organizations are unable to answer such questions, or only have a vague idea for various reasons. Either they are monitoring the process with a very limited scope, or the mechanisms for monitoring the process are not in place to allow such details to be available. We rarely find organizations with process owners having an end-to-end view of a process. The big picture of a process is not available to the decision makers on a real-time basis. Also, we have seen that a BPM cycle involves more than just automating a business process. Although modeling and analysis of the process plays an important part before a process is executed, the benefit is further highlighted by using Business Rules technology for added agility of the enterprise. One important factor that closes the loop for BPM is the aspect of monitoring the process on a continuous basis to pinpoint bottlenecks, as the process is executing within a business, and acts as a feedback for potential process improvement exercise. The need to monitor an organization's business processes, especially as part of a larger BPM initiatives, is gaining considerable acceptability and demand. Such monitoring is the primary job of BAM. What is BAM? BAM allows a business to monitor its business processes, and related business events being generated in real-time, and provides an assessment of business process health based on pre-defined KPIs. This allows greater operational visibility of the business to relevant process owners for assessment and decision-making via real-time information dashboards. BAM also allows users to take actions based on information available on the dashboards. Typically, systems providing BAM capabilities use business events to capture information from varied sources such as ERP, workflow, BPM, legacy systems, external partners, and suppliers. These data sources provide the necessary business measures, which are evaluated by the BAM against set KPIs, and provide the information in a user-friendly dashboard for the users. BPM, SOA, and BAM BPM, SOA, and BAM can be used as independent, isolated technologies. However, their benefits are compounded for a business if used together in a complementary fashion. As we can see in the following reference architecture, BAM works along with the services and process components to capture event-related information from a business and IT perspective, for analysis and reporting purposes. In this case, SOA enables an organization to have a robust and flexible IT infrastructure that can help it easily achieve its BAM goals by allowing events and data from different services to be available to BAM for decision-making and realtime analysis. In an SOA-based solution, the business events will be inputs for BAM that are provided from the services layer. The linkage is via the BPM route, or through an event-based integration layer provided by an ESB. We can refer to this relationship between BAM and SOA as being Service Oriented Activity Monitoring (SOAM), as today's organizational setup will provide this event information to various BAM services interfaces exposed by the business applications in an enterprise. In case of BPM, the business process describes the key activities required to fulfill the specified business action and its associated KPIs. These actions are executed as transactions using an orchestration engine and the underlying service layer. These transaction occurrences result in multiple process events to be created for each step within a transaction. BAM's primary focus is on capturing, analyzing, and reporting on the transactions and events created by the process running over the SOA platform. In case of BPM, the business process describes the key activities required to fulfill the specified business action and its associated KPIs. These actions are executed as transactions using an orchestration engine and the underlying service layer. These transaction occurrences result in multiple process events to be created for each step within a transaction. BAM's primary focus is on capturing, analyzing, and reporting on the transactions and events created by the process running over the SOA platform. BAM usually looks at collecting information about a process based on the following attributes: Quantity or Volume of Transactions or Events: One of the primary areas covered by BAM is the volume of events generated by a process. This is not just an IT metric, but more of a business-related metric to help business stakeholders analyze information points such as the number of orders shipped in a day, the number of trades made during trading hours, the number of helpdesk tickets closed by a call centre, and so on. Usually, we will define these KPIs in a process definition, and use BAM to raise alerts to the portfolio manager if the process is exceeding those values, for example, "Send an alert as soon as the stock portfolio value decreases more than 3% ". Time Bound Events: In this case, the BAM concentrates on time-related metrics such as helpdesk ticket process cycle time for high priority issues, general process cycle times, supply-related waiting time, and so on. Again, based on certain thresholds, alerts can be sent out, or the reports can be viewed by the management in real-time using customized dashboards. Faults: These are situations where the process is not running well. This could be due to a hardware fault, or a process related issue such as deadlocks, or some other issue. BAM helps in these scenarios by helping to identify areas of problems, and providing important metrics with respect to frequencies of such errors and their potential damage on process performance, and other dimensions such as cost, schedules, and so on. User Defined Events and Conditions: Apart from the general dimensions of volume, time, and errors in a process, a business user might want to define KPIs around specific business issues that need analysis. For example, for compliance requirements, a bank might be required to keep track of all high-value transactions to prevent money laundering. During implementation, the business analysts can define this KPI in the process model, which will then be implemented mostly by a rules engine, and the events generated will be used by BAM to provide statistical reports and dashboards based on the frequency of these transactions, specific regions and user types involved in such transactions, and so on. The real value of BAM, however, does not come only from analysis of individual events, and exceptions generated during process execution. BAM provides a mechanism to correlate aggregated process events to help with a cause and effect analysis, pattern matching, and so on, which provides immense value to today's businesses. Although not in the scope of this article, another area which is gaining a lot of attention in this area is Complex Event Processing or CEP. This can be a perfect vehicle for implementing BAM in an enterprise in order to solve complex business issues. CEP is based on a concept of analyzing a set of specific events from a range of possible events, and identifying patterns that could be meaningful for an organization. Among the many applications of CEP, one example we can use is that of 'Algorithmic Trading', where CEP can be used to analyze a huge amount of market data, assess favorable patterns for trading, and initiate trading in a market based on this. A lot of banks are using this technology for performing low-value trades, and assessing risk positions simultaneously. CEP then records this information as a 'fingerprint', and maintains a history to use when deciding whether to execute similar trades in the future. As it gathers more experience and intelligence, the BAM tool supporting CEP can start to refine its predictive capabilities, and conduct more efficient calculations.
Read more
  • 0
  • 0
  • 2685

article-image-tabs-jquery-ui-17
Packt
30 Nov 2009
7 min read
Save for later

Tabs in jQuery UI 1.7

Packt
30 Nov 2009
7 min read
The UI tabs widget is used to toggle visibility across a set of different elements, each element containing content that can be accessed by clicking on its heading which appears as an individual tab. The tabs are structured so that they line up next to each other, whereas the content sections are layered on top of each other, with only the top one visible. Clicking a tab will highlight the tab and bring its associated content panel to the top of the stack. Only one content panel can be open at a time. The following screenshot shows the different components of a set of UI tabs: A basic tab implementation The structure of the underlying HTML elements, on which tabs are based, is rigid and widgets require a certain number of elements for them to work. The tabs must be created from a list element (ordered or unordered) and each list item must contain an <a> element. Each link will need to have a corresponding element with a specified id that it is associated with the link's href attribute. We'll clarify the exact structure of these elements after our first example. In a new file in your text editor, create the following page: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html lang="en"> <head> <link rel="stylesheet" type="text/css" href="development-bundle/themes/smoothness/ui.all.css"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>jQuery UI Tabs Example 1</title> </head> <body> <div id="myTabs"> <ul> <li><a href="#a">Tab 1</a></li> <li><a href="#b">Tab 2</a></li> </ul> <div id="a">This is the content panel linked to the first tab,  it is shown by default.</div> <div id="b">This content is linked to the second tab and will be shown when its tab is clicked.</div> </div> <script type="text/javascript" src="development-bundle/jquery-1.3.2.js"></script> <script type="text/javascript" src="development-bundle/ui/ui.core.js"></script> <script type="text/javascript" src="development-bundle/ui/ui.tabs.js"></script> <script type="text/javascript"> $(function(){ $("#myTabs").tabs(); }); </script> </body></html> Save the code as tabs1.html in your jqueryui working folder. Let's review what was used. The following script and CSS resources are needed for the default tab widget instantiation: ui.all.css jquery-1.3.2.js ui.core.js ui.tabs.js A tab widget consists of several standard HTML elements arranged in a specific manner (these can be either hardcoded into the page, or added dynamically, or can be a mixture of both depending on the requirements of your implementation). An outer container element, which the tabs method is called on A list element( <ul> or <ol>) An <a> element for each tab An element for the content of each tab The first two elements within the outer container make the clickable tab headings, which are used to show the content section that is associated with the tab. Each tab should include a list item containing the link. The href attribute of the link should be set as a fragment identifier, prefixed with #. It should match the id attribute of the element that forms the content section, with which it is associated. The content sections of each tab are created by the elements. The id attribute is required and will be targeted by its corresponding element. We've used elements in this example as the content panels for each tab, but other elements, such as elements can also be used. The elements discussed so far, along with their required attributes, are the minimum that are required from the underlying markup.We link to several <script> resources from the library at the bottom of the <body> before its closing tag. Loading scripts last, after stylesheets and page elements is a proven technique for improving performance. After linking first to jQuery, we link to the ui.core.js file that is required by all components (except the effects, which have their own core file). We then link to the component's source file that in this case is ui.tabs.js.After the three required script files from the library, we can turn to our custom < script> element in which we add the code that creates the tabs. We simply use the $(function(){}); shortcut to execute our code when the document is ready. We then call the tabs() widget method on the jQuery object, representing our tabs container element (the <ul> with an id of myTabs).When we run this file in a browser, we should see the tabs as they appeared in the first screenshot of this article(without the annotations of course). Tab CSS framework classes Using Firebug for Firefox (or another generic DOM explorer) we can see that a variety of class names are added to the different underlying HTML elements that the tabs widget is created from, as shown in the following screenshot: Let's review these briefly. To the outer container < div> the following class names are added: Class name Purpose ui-tabs Allows tab-specific structural CSS to be applied. ui-widget Sets generic font styles that are inherited by nested elements. ui-widget-content Provides theme-specific styles. ui-corner-all Applies rounded corners to container. The first element within the container is the < ul> element. This element receives the following class names: Class name Purpose ui-tabs-nav Allows tab-specific structural CSS to be applied. ui-helper-reset Neutralizes browser-specific styles applied to <ul> elements. ui-helper-clearfix Applies the clear-fix as this element has children that are floated. ui-widget-header Provides theme-specific styles. ui-corner-all Applies rounded corners. The individual < li> elements are given the following class names: Class name Purpose ui-state-default Applies theme-specific styles. ui-corner-top Applies rounded corners to the top edges of the elements. ui-tabs-selected This is only applied to the active tab. On page load of the default implementation this will be the first tab. Selecting another tab will remove this class from the currently selected tab and apply it to the new tab. ui-state-active Applies theme-specific styles to the currently selected tab. This class name will be added to the tab that is currently selected, just like the previous class name. The reason there are two class names is that ui-tabs-selected provides the functional CSS, while ui-state-active provides the visual, decorative styles. The < a> elements within each < li> are not given any class names, but they still have both structural and theme-specific styles applied to them by the framework. Finally, the elements that hold each tab's content are given the following class names: Class name Purpose ui-tabs-panel Applies structural CSS to the content panels ui-widget-content Applies theme-specific styles ui-corner-bottom Applied rounded corners to the bottom edges of the content panels All of these classes are added to the underlying elements automatically by the library, we don't need to manually add them when coding the page. As these tables illustrate, the CSS framework supplies the complete set of both structural CSS styles that control how the tabs function and theme-specific styles that control how the tabs appear, but not how they function. We can easily see which selectors we'll need to override if we wish to tweak the appearance of the widget, which is what we'll do in the following section.
Read more
  • 0
  • 0
  • 4260
article-image-navigating-your-site-using-codeigniter-17-part-2
Packt
30 Nov 2009
9 min read
Save for later

Navigating Your Site using CodeIgniter 1.7: Part 2

Packt
30 Nov 2009
9 min read
Designing a better view At this stage, you might ask: Why are we going through so much effort to serve a simple HTML page? Why not put everything in one file? For a simple site, that's a valid point—but whoever heard of a simple site? One of the coolest things about CI is the way it helps us to develop a consistent structure. So, as we add to and develop our site, it is internally consistent, well laid out, and simple to maintain. At the start, we need to take these three common steps: Write a view page Write a stylesheet Update our config file to specify where the stylesheet is After this is done, we need to update our controller to accept parameters from the URL, and pass variables to the view. First, let's redesign our view and save it as testview.php, at /www/codeigniter/application/views/testview.php. <html><head><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0Strict//EN'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'><html ><title>Web test Site</title><link rel="stylesheet" type="text/css" href="<?php echo$base."/".$css;?>"></head><body><h1><?php echo $mytitle; ?> </h1><p class='test'> <?php echo $mytext; ?> </p></body></html> It's still mostly HTML, but notice the PHP "code islands" in the highlighted lines. You'll notice that the first bits of PHP code build a link to a stylesheet. Let's save a simple stylesheet as styles.css, at www/codeigniter/css/styles.css. It just says: h1{margin: 5px;padding-left: 10px;padding-right: 10px;background: #ffffff;color: blue;width: 100%;font-size: 36px;}.test{margin: 5px;padding-left: 10px;padding-right: 10px;background: #ffffff;color: red;width: 100%;font-size: 36px;} This gives us two styles to play with, and you'll see we've used both of them in the view. Firstly, let's add an entry to the config file: $config['css'] = 'css/styles.css'; This is simply to tell the name and address of the CSS file that we've just written to the site. But note that the link to the stylesheet is referenced at $base/$css: Where do those variables, $base and $css, get their values? And come to think of it, those variables $mytitle and $mytext at the end of the code? We need a new controller! Designing a better controller Now, we need a new controller. We'll call it Start and save it as start.php, at /www/codeigniter/application/controllers/start.php. This controller has to do several things: Call a view Provide the view with the base URL and the location of the CSS file we just wrote Provide the view with some data—it's expecting a title ($mytitle) and some text ($mytext) Lastly, accept a parameter from the user (that is using the URL request) In other words, we have to populate the variables in the view. So let's start with our Start controller. This is an OO class: <?phpclass Start extends Controller{var $base;var $css; Notice that here we've declared the $base and $css (the CSS filename) as variables or class properties. This saves us from having to redeclare them if we write more than one function in each class. But you can define and use them as local variables within one function, if you prefer. The constructor function now defines the properties we've declared, by looking them up in the config file. To do this, we use the syntax: $this->config->item('name_of_config_variable'); As in: function Start(){parent::Controller();$this->base = $this->config->item('base_url');$this->css = $this->config->item('css');} CI recovers whatever we entered in the config file against that name. Using this system, no matter how many controllers and functions we write, we'll have to change these fundamental variables only once. This is true even if our site becomes so popular that we have to move it to a bigger server. Getting parameters to a function Now, within the Start controller class, let's define the function that will actually do the work. function hello($name = 'Guest'){$data['css'] = $this->css;$data['base'] = $this->base;$data['mytitle'] = 'Welcome to this site';$data['mytext'] = "Hello, $name, now we're getting dynamic!";$this->load->view('testview', $data);} This function expects the parameter $name, but you can set a default value—myfunction($myvariable = 0), which it uses to build the string assigned to the $mytext variable. Well, as we just asked, where does that come from? In this case, it needs to come from the URL request, where it will be the third parameter. So, it comes through the HTTP request: http://127.0.0.1/codeigniter/start/hello/Jose This example code doesn't "clean" the passed variable Jose, or check it in any way. You might want to do this while writing the code. We'll look at how to check form inputs. Normally, variables passed by hyperlinks in this way are generated by your own site. A malicious user can easily add his or her own, just by sending a URL such as: http://www.mysite.com/index.php/start/hello/my_malicious_variable. So, you might want to check that the variables you receive are within the range you expect, before handling them. The last segment of the URL is passed to the function as a parameter. In fact, you can add more segments of extra parameters if you like, subject to the practical limits imposed by your browser. Let's recap on how CI handles URLs, since we've covered it all now: URL segment   What it does   http://www.mysite.com   The base URL that finds your site.   /index.php   Finds the CI router that sets about reading the rest of the URL and selecting the correct route into your site. If you have added the .htaccess file in the previous chapter, this part will not be visible, but will still work as supposed.   /start   The name of the controller that CI will call (If no name is set, CI will call whichever default controller you've specified).   /hello   The name of a function that CI will call, inside the selected controller (If no function is specified, it defaults to the index function, unless you've used _remap).   /Jose   CI passes this to the function as a variable.   If there is a further URL segment, for example, /bert   CI passes this to the function as the second variable. More variables   CI will pass further URL segments as consequent variables.   Passing data to a view Let's go back to the hello function: function hello($name){$data['css'] = $this->css;$data['base'] = $this->base;$data['mytitle'] = 'Welcome to this site';$data['mytext'] = "Hello, $name, now we're getting dynamic!";$this->load->view('testview', $data);} Notice how the hello() function first creates an array called $data, taking a mixture of object properties set up by the constructor and text. Then it loads the view by name, with the array it has just built as the second parameter. Behind the scenes, CI makes good use of another PHP function—extract(). This takes each value in the $data array and turns it into a new variable in its own right. So, the $data array that we've just defined is received by the view as a series of separate variables; $text (equal to "Hello, $name, now we're getting dynamic"), $css (equal to the value from the config file), and so on. In other words, when built, the $data array looks like this: Array([css] => 'mystyles.css';[base] => 'http://127.0.0.1/packt';[mytitle] => 'Welcome to this site';[mytext] => 'Hello, fred, now we're getting dynamic!';) But on its way to the view, it is unpacked, and the following variables are created in the view to correspond to each key/value pair in the array: $css = 'mystyles.css';$base = 'http://127.0.0.1/packt';$mytitle = 'Welcome to this site';$mytext = 'Hello, fred, now we're getting dynamic!';) Although you can only pass one variable to a view, you can pack a lot of information into it. Each value in the $data array can itself be another array, so you can pass pieces of information to the view in a tightly structured manner. Now navigate to http://127.0.0.1/codeigniter/start/hello/jose (note that the URL is different—it is looking for the start function we wrote in the index controller) and you'll see the result—a dynamic page written using MVC architecture. (well, VC at least! We haven't really used the M yet). You can see that the parameter jose is the last segment of the URL. It has been passed into the function, and then to the view. Please remember that your view must be written in parallel with your controller. If the view does not expect and make a place for a variable, it won't be displayed. If the view is expecting a variable to be set and it isn't, you are likely to get an error message (your view can of course accept variables conditionally). Also, a controller can use more than one view; this way we can separate our pages into sections such as the header, the menu, and so on. Each of these views can be nested one inside the other. Child views can even inherit variables passed by the controller to their parent view. Loading a view from inside another view is very easy; just put something like this PHP snippet in your HTML code: <body><div id="menu"><?php $this->load->view('menu'); ?> This way we can load a view inside a view, with all variables in the first one also available into the nested one.
Read more
  • 0
  • 0
  • 3765

article-image-drag-and-drop-yui-part-2
Packt
30 Nov 2009
12 min read
Save for later

Drag-and-Drop with the YUI: Part-2

Packt
30 Nov 2009
12 min read
Scripting DragDrop There are two ways that we could go about achieving our objective. We could take the easy way and treat each draggable object as an independent module, with its own independent properties and event handlers. This would make the code simpler, but would mean that we would require a good deal more of it. If there are just one or two objects on your page which can be dragged and dropped then this way is fine. However, when you begin to have more than just a couple of objects that can be moved, the amount of code required to handle these objects efficiently increases dramatically. The second way may be a little more complex and therefore will require a greater degree of understanding. However, this way allows for sharing properties and event handlers across similar drag-and-drop objects. This reduces the overall footprint of your application and saves us an incredible amount of typing. Creating Individual Drag Objects We can look at both methods, so you can see just how much work the second way saves us. We'll start with the easy method. Add the following <script> tag directly before the closing </body> tag: <script type="text/javascript">//create the namespace object for this exampleYAHOO.namespace("yuibook.dd");//define the setDDs functionYAHOO.yuibook.dd.setDDs = function() {//detect the useragentvar ua = YAHOO.env.ua;if (ua.ie != 0) {ua.data = "ie";}//define variablesvar basketTotal = 0;var basketTot = 0;var Dom = YAHOO.util.Dom;//create the 3 DragDropProxy objectsvar dd1 = new YAHOO.util.DDProxy("prod1");dd1.isTarget = false;dd1.scroll = false;var dd2 = new YAHOO.util.DDProxy("prod2");dd2.isTarget = false;dd2.scroll = false;var dd3 = new YAHOO.util.DDProxy("prod3");dd3.isTarget = false;dd3.scroll = false;var basket = new YAHOO.util.DDTarget("basket");//define function to call when dd1 starts being draggeddd1.startDrag = function() {//set cursor position to top-left of proxydd1.setDelta(0,0);}//define function to call when dd1 stops being dragdeddd1.endDrag = function() {}//define function to call when dd1 enters basketdd1.onDragEnter = function(e, id) {//has dd1 been dragged into basket?if (id == "basket") {//add 1 to the total number of itemsbasketTotal += 1;var tot = YAHOO.util.Dom.get("basketTotal")tot.innerHTML = basketTotal;//create new p element to hold product summaryvar p = document.createElement("p");Dom.addClass(p, "prod");p.id = "prod" + basketTotal;//add icon for product 1 to basketvar ico = document.createElement("img");ico.setAttribute("src", "images/prod1_ico.jpg");ico.id = "imageico" + basketTotal;Dom.addClass(ico, "icon");//add product 1 summary to basketp.appendChild(ico);Dom.get("basketBody").appendChild(p);//create new p element for product 1 titlevar p2 = document.createElement("p");var info = Dom.get("prod1info");//is the browser IE?if (ua.data == "ie") {var infos = info.innerHTML.split("<BR>");} else {var infos = info.innerHTML.split("<br>");}//set product 1 titlevar title = document.createTextNode(infos[0]);Dom.addClass(p2, "prodTitle");p2.id = "prodTitle" + basketTotal;//add title to basketp2.appendChild(title);Dom.insertAfter(p2, Dom.get(ico));//create p element for product 1 pricevar p3 = document.createElement("p");var price = document.createTextNode(infos[1]);Dom.addClass(p3, "prodPrice");p3.id = "prodPrice" + basketTotal;//add product 1 price to basketp3.appendChild(price);Dom.insertAfter(p3, Dom.get(p2));//update total basket priceprice = Dom.get(p3).innerHTML;var rawPrice = price.slice(1,6);var cost = parseFloat(rawPrice);basketTot += cost;var newBasketTot = Dom.get("basketCost");newBasketTot.innerHTML = basketTot;}}//define function to call when dd2 starts being draggeddd2.startDrag = function() {dd2.setDelta(0,0);}//define function to call when dd2 stops being draggeddd2.endDrag = function() {}//define function to call when dd2 enters basketdd2.onDragEnter = function(e, id) {if (id == "basket") {//add 1 to the total number of itemsbasketTotal += 1;var tot = YAHOO.util.Dom.get("basketTotal")tot.innerHTML = basketTotal;//create new p element to hold product summaryvar p = document.createElement("p");Dom.addClass(p, "prod");p.id = "prod" + basketTotal;//add icon for product 2 to basketvar ico = document.createElement("img");ico.setAttribute("src", "images/prod2_ico.jpg");ico.id = "imageico" + basketTotal;Dom.addClass(ico, "icon");//add product 2 summary to basketp.appendChild(ico);Dom.get("basketBody").appendChild(p);//create new p element for product 2 titlevar p2 = document.createElement("p");var info = Dom.get("prod2info");//is the browser IE?if (ua.data == "ie") {var infos = info.innerHTML.split("<BR>");} else {var infos = info.innerHTML.split("<br>");}//set product 2 titlevar title = document.createTextNode(infos[0]);Dom.addClass(p2, "prodTitle");p2.id = "prodTitle" + basketTotal;//add title to basketp2.appendChild(title);Dom.insertAfter(p2, Dom.get(ico));//create p element for product 2 pricevar p3 = document.createElement("p");var price = document.createTextNode(infos[1]);Dom.addClass(p3, "prodPrice");p3.id = "prodPrice" + basketTotal;//add product 2 price to basketp3.appendChild(price);Dom.insertAfter(p3, Dom.get(p2));//update total basket priceprice = Dom.get(p3).innerHTML;var rawPrice = price.slice(1,6);var cost = parseFloat(rawPrice);basketTot += cost;var newBasketTot = Dom.get("basketCost");newBasketTot.innerHTML = basketTot;}}//define function to call when dd3 starts being draggeddd3.startDrag = function() {dd3.setDelta(0,0);}//define function to call when dd3 stops being draggeddd3.endDrag = function() {}//define function for when dd3 enters basketdd3.onDragEnter = function(e, id) {if (id == "basket") {//add 1 to the total number of itemsbasketTotal += 1;var tot = YAHOO.util.Dom.get("basketTotal")tot.innerHTML = basketTotal;//create new p element to hold product summaryvar p = document.createElement("p");Dom.addClass(p, "prod");p.id = "prod" + basketTotal;//add icon for product 3 to basketvar ico = document.createElement("img");ico.setAttribute("src", "images/prod3_ico.jpg");ico.id = "imageico" + basketTotal;Dom.addClass(ico, "icon");//add product 3 summary to basketp.appendChild(ico);Dom.get("basketBody").appendChild(p);//create new p element for product 3 titlevar p2 = document.createElement("p");var info = Dom.get("prod3info");//is the browser IE?if (ua.data == "ie") {var infos = info.innerHTML.split("<BR>");} else {var infos = info.innerHTML.split("<br>");}//set product 3 titlevar title = document.createTextNode(infos[0]);Dom.addClass(p2, "prodTitle");p2.id = "prodTitle" + basketTotal;//add title to basketp2.appendChild(title);Dom.insertAfter(p2, Dom.get(ico));//create p element for product 3 pricevar p3 = document.createElement("p");var price = document.createTextNode(infos[1]);Dom.addClass(p3, "prodPrice");p3.id = "prodPrice" + basketTotal;//add product 3 price to basketp3.appendChild(price);Dom.insertAfter(p3, Dom.get(p2));//update total basket priceprice = Dom.get(p3).innerHTML;var rawPrice = price.slice(1,6);var cost = parseFloat(rawPrice);basketTot += cost;var newBasketTot = Dom.get("basketCost");newBasketTot.innerHTML = basketTot;}}}//execute setDDs when DOM is readyYAHOO.util.Event.onDOMReady(YAHOO.yuibook.dd.setDDs);</script> All of the code here sits within the setDDs() function, which is called using the Event utility's onDOMReady() method. The first section of code within the setDDs() function uses the .env.ua() method of the YAHOO global object to determine the user-agent string of the browsing environment. We can use this as a quick and easy way of detecting the browser being used to view the page. The ie property exists within the ua object even if IE is not in use, but if it isn't in use, the property is set to 0. Therefore, if the ie property does not equal to 0 it means that IE is the browser currently being used. In this case, the ie property will hold an integer representing the version of IE in use. When IE is being used, we set the data property of our ua variable to the string ie. We then create a series of variables for use in the script. The last variable is created purely for convenience. We'll be making heavy use of the DOM utility during this example, so defining that first part of the DOM call as a short variable helps make things easier on us. Next we create all three of the individual DDProxy objects. Remember, in this implementation, each object has to have its own properties and event handlers defined for it. We also define the basket as a DDTarget so that we can make use of the .onDragEnter() method. Because we want each product to interact only with our shopping basket and not the other products on the page, we have to set the .isTarget property to false. As well as being able to specifically create drop targets using the YAHOO.util.DDTarget class, any drag object is by default also a drop target. Additionally, we can switch off the .scroll property, which causes the viewport to scroll indefinitely when the dragged object exceeds the window boundary. Using DragDrop Events Three event handlers are required for this example: startDrag, endDrag, and onDragEnter. The startDrag event fires as soon as the left mouse button has been held down for the required length of time on a drag object, or the pointer moves the specified number of pixels. The .setDelta() method used in the startDrag event handler allows us to control where the pointer is relative to the drag object, or in this case, the proxy element. By specifying 0,0 as arguments for this method, we are instructing the pointer to appear at the top-left corner of the proxy element. This is needed so that the element is placed back where it began instead of where the pointer was relative to the drag object when the drag began. The endDrag event fires when a mouseup event is detected on the object being dragged. The anonymous function here has a very special purpose, even though it is just an empty function.What it does is ensure that the item being dragged is returned to its original position once it has been dropped instead of remaining where it was dropped. This is important because if we didn't keep the listing pictures in their proper locations, the page would soon be littered with abandoned drag objects. The onDragEnter event fires when the moving object is dragged over a legal target. Since the shopping basket is the only valid target on the page, this will fire whenever a product object is dragged over the basket. This function is where the bulk of our code lies. Two arguments are specified for this function. The first is the event object, which is automatically passed to our handler. The second argument is the id of the element that triggered the event, which in this example will be the basket. We first use our YAHOO.util.Dom shortcut to get the <span> element displaying the number of items in the basket, then use the innerHTML property to alter this value in accordance with the basketTotal variable. We create a new paragraph element and give it a class of prod. This new element will act as a container for a short summary of the item placed in the basket. We can go ahead and create the different items that will make up this short description of the product that has been purchased. A new <img> element is created and stored in the ico variable. Its src attribute is set to the icon representing the product. We then give it a class name so that we can style it and an id attribute so that we can identify it. Once created and configured, we can append the <img> to the new <p> element, and then append the <p> element to the body of the basket. Now let's work on extracting some of the listing description to display in the basket. We create another new <p> element and give it a class of prodTitle. We then need to do more detection to determine which product was dropped, getting the full listing text of the product in the title variable once we have. Each part of the listing text is separated by a <br> element, so we can create an array of each different bit of information contained in the listing text using the .split() method. This is the part of the script where we use the information gathered from the ua property earlier on. IE for some reason capitalizes all HTML elements in the DOM. This means that IE sees <BR> tags, while other browsers see <br>, and is the reason we need the if statement to determine the browser in use. The first item in the infos array is the name of the product, so we can use this as the title for the product summary and create a new textNode based on it. This title element is then inserted into the DOM directly after the icon element using the DOM utility's .insertAfter() method, which takes the element to insert and the element it should be inserted after as arguments. For good measure, let's add the price of the product to the product summary. A final element is created to hold a new textNode comprised of the second item in the infos array, which happens to be the price of the product. The class for the new <p> element is set and it is then inserted as a sibling of the previous element that was created. At the bottom of our basket is a price indicator showing the total cost of all items in the basket; we can easily update this using the same method as we updated the basket contents total earlier on. We recycle the price variable, updating it with the HTML element from the basket. As the price is currently a text string rather than a number, we have to convert it. Before we can do this however, we need to remove the currency symbol from the front of it, which we can do with the .slice() method. Then we can use the standard JavaScript parseFloat math function to convert the remaining string into a true floating-point number. We can then update the current cost by adding the cost of the dropped product to it. Finally, we set the innerHTML property of the basketCost span element to the new total. As each drag object is completely independent, the rest of our script is made up of identical event handlers tied to the other drag objects (products 2 and 3). This is what bloats our code to three times the size it actually needs to be, and imagine how much typing would need to be done if there were 30 products on the page
Read more
  • 0
  • 0
  • 1295
Modal Close icon
Modal Close icon