Fix all.php first-time failure, improve HTML detection, send 403 forbidden.
[csrf-magic.git] / README.txt
blobcb48be6a53f2e18412bb811e8ac717db33185689
2 [[  csrf-magic  ]]
4 Add the following line to the top of all web-accessible PHP pages. If you have
5 a common file included by everything, put it there.
7     include_once '/path/to/csrf-magic.php';
9 Do it, test it, then forget about it. csrf-magic is protecting you if nothing
10 bad happens. Read on if you run into problems.
13 1.  WHAT DOES IT DO?
15 CSRF, or cross-site request forgery, is a relatively new attack vector on
16 websites today.  It involves an attacker tricking a browser into performing
17 an action on another website.  For example, Bob is the human resources manager
18 for a large and important company.  He has the ability to hire and fire with
19 a click of a button... specifically, a web form button.  Mallory, as a practical
20 joke, decides to setup a CSRF attack against Bob; she crafts a webpage which
21 submits a form onto the internal website that performs hirings and firings; then
22 she sends Bob an email to this webpage.  The next day, every employee wakes up
23 to find a rather nasty pink slip in their inbox.
25 The current standard for preventing CSRF is creating a nonce that every user
26 submits with any form he/she submits.  This is reasonably effective [1], but
27 incredibly tedious work; if you were hand-writing your forms or have multiple
28 avenues for POST data to enter your application, adding CSRF protection may not
29 seem worth the trouble (trust me, it certainly is).
31 This is where csrf-magic comes into play.  csrf-magic uses PHP's output
32 buffering capabilities to dynamically rewrite forms and scripts in your document.
33 It will also intercept POST requests and check their token (various algorithms
34 are used, some generate nonces, some generate user-specific tokens).  This means
35 with a traditional website with forms, you can drop it into your application,
36 and forget about it!
39 2.  AJAX
41 csrf-magic has the ability to dynamically rewrite AJAX requests which use
42 XMLHttpRequest.  However, due to the invasiveness of this procedure, it is
43 not enabled by default.  You can enable it by adding this code before you
44 include csrf-magic.php.
46     function csrf_startup() {
47         csrf_conf('rewrite-js', '/web/path/to/csrf-magic.js');
48     }
49     // include_once '/path/to/csrf-magic.php';
51 (Be sure to place csrf-magic.js somewhere web accessible).  csrf-magic.js will
52 automatically detect and play nice with the following JavaScript frameworks:
54     * jQuery
55     * Prototype
56     * script.aculo.us (via Prototype)
57     * MooTools
58     * Yahoo UI Library
59     * Ext
60     * Dojo
62 If you are not using any of these JavaScript libraries, AJAX requests will
63 only work for browsers with support for XmlHttpRequest.prototype (this excludes
64 all versions of Internet Explorer).
66 To rewrite your own JavaScript library to use csrf-magic.js, you should modify
67 your function that generates XMLHttpRequest to have this at the end:
69     return new CsrfMagic(xhrObject);
71 With whatever xhrObject may be. If you have literal instances of XMLHttpRequest
72 in your code, find and replace ''new XMLHttpRequest'' with ''new CsrfMagic''
73 (CsrfMagic will automatically instantiate an XMLHttpRequest object in a
74 cross-platform manner as necessary).
76 If you don't want csrf-magic monkeying around with your XMLHttpRequest object,
77 you can manually rewrite your AJAX code to include the variable. The important
78 information is stored in the global variables csrfMagicName and csrfMagicToken.
79 CsrfMagic.process may also be of interest, as it takes one parameter, a
80 querystring, and prepends the CSRF token to the value.
83 3.  CONFIGURE
85 csrf-magic has some configuration options that you can set inside the
86 csrf_startup() function. They are described in csrf-magic.php, and you can
87 set them using the convenience function csrf_conf($name, $value).
89 For example, this is a recommended configuration:
91     /**
92      * This is a function that gets called if a csrf check fails. csrf-magic will
93      * then exit afterwards.
94      */
95     function my_csrf_callback() {
96         echo "You're doing bad things young man!";
97     }
99     function csrf_startup() {
101         // While csrf-magic has a handy little heuristic for determining whether
102         // or not the content in the buffer is HTML or not, you should really
103         // give it a nudge and turn rewriting *off* when the content is
104         // not HTML. Implementation details will vary.
105         if (isset($_POST['ajax'])) csrf_conf('rewrite', false);
107         // This is a secret value that must be set in order to enable username
108         // and IP based checks. Don't show this to anyone. A secret id will
109         // automatically be generated for you if the directory csrf-magic.php
110         // is placed in is writable.
111         csrf_conf('secret', 'ABCDEFG123456');
113         // This enables JavaScript rewriting and will ensure your AJAX calls
114         // don't stop working.
115         csrf_conf('rewrite-js', '/csrf-magic.js');
117         // This makes csrf-magic call my_csrf_callback() before exiting when
118         // there is a bad csrf token. This lets me customize the error page.
119         csrf_conf('callback', 'my_csrf_callback');
121         // While this is enabled by default to boost backwards compatibility,
122         // for security purposes it should ideally be off. Some users can be
123         // NATted or have dialup addresses which rotate frequently. Cookies
124         // are much more reliable.
125         csrf_conf('allow-ip', false);
127     }
129     // Finally, include the library
130     include_once '/path/to/csrf-magic.php';
132 Configuration gets stored in the $GLOBALS['csrf'] array.
135 4.  THANKS
137 My thanks to Chris Shiflett, for unintentionally inspiring the idea, as well
138 as telling me the original variant of the Bob and Mallory story,
139 and the Django CSRF Middleware authors, who thought up of this before me.
141 http://www.thespanner.co.uk/2007/08/20/protection-against-csrf/ is interesting
142 esp the frame breaker which we can automatically write in.
145 5.  FOOTNOTES
147 [1] There is an experimental attack in which a user makes an invisible iframe
148     of the website being attacked and overlays this on-top of an element on
149     their page that a user would normally click.  This iframe has a different
150     button from the other website which activates the action.  Nonces will
151     not protect against this type of attack, and csrf-magic doesn't deal with
152     this type of attack.
154     See also:
155         http://own-the.net/cat_CSRF-(XSRF)_news.html