Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v1.1.0 #16

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 126 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# News

## 1.1.0 released 2020-02-23

Bug Fixes

- In some server environments, being behind a load balancer and enabling IP
restrictions would be ineffective as other users would all appear to be from
the same remote address

Features

- Allow logging of the CSRF process which is useful for third party develoeprs
when they are trying to incorporate the library to see what steps are being
taken and from where.

Configuration var: `log_file`

- Allow logging to also be echoed to console

Configuration var: `log_echo`

- Allow specifying the location of the CSRF secret file as some package
maintainers may prefer to relocate the secret file to a hidden location that
is readable only when installing the package and not be the application.

Configuration var: `path_secret`

- Allow specifying the startup function as some callers may wish to keep in line
with their own code formats.

Configuration var `startup_func`

- Allow configuration of which hashing function to use. It is expected that the
user configuring this option will known what hash functions are availble or it
could cause runtime errors.

Configuration var `hash`

- Allow use of session_id() to be configured via configuration variable so that
other mechanisms can be utilsed instead.

Configuration var `session`

## 1.0.5 released 2014-07-24

Bug Fixes

- In some server environments, IP address was not being detected properly.
Thanks Bianka Martinovic for reporting.

Security Fixes

- Hashing now uses an HMAC to prevent length extension attacks.

Features

- New option 'disable' which allows you to conditionally disable the CSRF
protection. Requested by Justin Carlson.

## 1.0.4 released 2013-07-17

Security Fixes

- When secret key was not explicitly set, it was not being used by the
`csrf_hash()` function. Thanks sparticvs for reporting.

Features

- The default 'CSRF check failed' page now offers a handy 'Try again' button,
which resubmits the form.

Bug Fixes

- The fix for 1.0.3 inadvertantly turned off XMLHttpRequest
overloading for all browsers; it has now been fixed to only
apply to IE.

## 1.0.3 released 2012-01-31

Bug Fixes

- Internet Explorer 8 adds support for XMLHttpRequest.prototype,
but this support is broken for method overloading. We
explicitly disable JavaScript overloading for Internet Explorer.
Thanks Kelly Lu for reporting. <[email protected]>

- A global declaration was omitted, resulting in a variable
not being properly introduced in PHP 5.3. Thanks Whitney Beck for
reporting. <[email protected]>

## 1.0.2 released 2009-03-08

Security Fixes

- Due to a typo, csrf-magic accidentally treated the secret key
as always present. This means that there was a possible CSRF
attack against users without any cookies. No attacks in the
wild were known at the time of this release. Thanks Jakub
Vrána for reporting.

## 1.0.1 released 2008-11-02

### New Features

- Support for composite tokens; this also fixes a bug with using
IP-based tokens for users with cookies disabled.

- Native support cookie tokens; use csrf_conf('cookie', $name) to
specify the name of a cookie that the CSRF token should be
placed in. This is useful if you have a Squid cache, and need
to configure it to ignore this token.

- Tips/tricks section in README.txt.

- There is now a two hour expiration time on all tokens. This
can be modified using csrf_conf('expires', $seconds).

- ClickJacking protection using an iframe breaker. Disable with
csrf_conf('frame-breaker', false).

Bug Fixes

- CsrfMagic.send() incorrectly submitted GET requests twice,
once without the magic token and once with the token. Reported
by Kelly Lu <[email protected]>.
69 changes: 0 additions & 69 deletions NEWS.txt

This file was deleted.

160 changes: 160 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
# CSRF Magic

Add the following line to the top of all web-accessible PHP pages. If you have a
common file included by everything, put it there.

```php
include_once '/path/to/csrf-magic.php';
```

Do it, test it, then forget about it. csrf-magic is protecting you if nothing
bad happens. Read on if you run into problems.

## TIPS AND TRICKS

* If your JavaScript and AJAX is persistently getting errors, check the AJAX
section below on how to fix.

* The CSS overlay protection makes it impossible to display your website in
frame/iframe elements. You can disable it with csrf_conf('frame-breaker',
false) in your csrf_startup() function.

* csrf-magic will start a session. To disable, use csrf_conf('auto-session',
false) in your csrf_startup() function.

* The default error message is a little user unfriendly. Write your own
function which outputs an error message and set csrf_conf('callback',
'myCallbackFunction') in your csrf_startup() function.

* Make sure csrf_conf('secret', 'ABCDEFG') has something random in it. If the
directory csrf-magic.php is in is writable, csrf-magic will generate a secret
key for you in the csrf-secret.php file.

* Remember you can use auto_prepend to include csrf-magic.php on all your pages.
You may want to create a stub file which you can include that includes
csrf-magic.php as well as performs configuration.

* The default expiration time for tokens is two hours. If you expect your users
to need longer to fill out forms, be sure to enable double submission when the
token is invalid.

## AJAX

csrf-magic has the ability to dynamically rewrite AJAX requests which use
XMLHttpRequest. However, due to the invasiveness of this procedure, it is not
enabled by default. You can enable it by adding this code before you include
csrf-magic.php.

```php
function csrf_startup() {
csrf_conf('rewrite-js', '/web/path/to/csrf-magic.js');
}
// include_once '/path/to/csrf-magic.php';
```

**NOTE:** *Be sure to place csrf-magic.js somewhere web accessible.*

The default method CSRF Magic uses to rewrite AJAX requests will only work for
browsers with support for XmlHttpRequest.prototype (this excludes all versions
of Internet Explorer). See this page for more information:
[Prototypes and xmlhtprequest](http://stackoverflow.com/questions/664315/internet-explorer-8-prototypes-and-xmlhttprequest)

However, csrf-magic.js will automatically detect and play nice with the
following JavaScript frameworks:

* jQuery

* Prototype

* MooTools

* Ext

* Dojo

**Note:** As of 2013-07-16, it has been a long time since this manual support
has been updated, and some JavaScript libraries have placed their copies of XHR
in local variables in closures, which makes it difficult for us to monkey-patch
it in automatically.)

To rewrite your own JavaScript library to use csrf-magic.js, you should modify
your function that generates XMLHttpRequest to have this at the end:

```php
return new CsrfMagic(xhrObject);
```

With whatever xhrObject may be. If you have literal instances of XMLHttpRequest
in your code, find and replace `new XMLHttpRequest` with `new CsrfMagic`
(CsrfMagic will automatically instantiate an XMLHttpRequest object in a
cross-platform manner as necessary).

If you don't want csrf-magic monkeying around with your XMLHttpRequest object,
you can manually rewrite your AJAX code to include the variable. The important
information is stored in the global variables csrfMagicName and csrfMagicToken.
CsrfMagic.process may also be of interest, as it takes one parameter, a
querystring, and prepends the CSRF token to the value.

## BASIC CONFIGURATION

csrf-magic has some configuration options that you can set inside the
`csrf_startup()` function. They are described in csrf-magic.php, and you can set
them using the convenience `function csrf_conf($name, $value)`.

For example, this is a recommended configuration suggested by the upstream
providers. It should be noted that Cacti has a custom implementation of this
which is included with this repository.

```php
/**
* This is a function that gets called if a csrf check fails. csrf-magic will
* then exit afterwards.
*/
function my_csrf_callback() {
echo "You're doing bad things young man!";
}

function csrf_startup() {

// While csrf-magic has a handy little heuristic for determining whether
// or not the content in the buffer is HTML or not, you should really
// give it a nudge and turn rewriting *off* when the content is
// not HTML. Implementation details will vary.
if (isset($_POST['ajax'])) csrf_conf('rewrite', false);

// This is a secret value that must be set in order to enable username
// and IP based checks. Don't show this to anyone. A secret id will
// automatically be generated for you if the directory csrf-magic.php
// is placed in is writable.
csrf_conf('secret', 'ABCDEFG123456');

// This enables JavaScript rewriting and will ensure your AJAX calls
// don't stop working.
csrf_conf('rewrite-js', '/csrf-magic.js');

// This makes csrf-magic call my_csrf_callback() before exiting when
// there is a bad csrf token. This lets me customize the error page.
csrf_conf('callback', 'my_csrf_callback');

// While this is enabled by default to boost backwards compatibility,
// for security purposes it should ideally be off. Some users can be
// NATted or have dialup addresses which rotate frequently. Cookies
// are much more reliable.
csrf_conf('allow-ip', false);

}

// Finally, include the library
include_once '/path/to/csrf-magic.php';
```

The configuration for CSRF is stored in the PHP global array GLOBALS['csrf']
which is applied from csrf-conf.php in the same directory as the csrf-magic.php
and should be read to see what additional settings are available.

## THANKS

My thanks to Chris Shiflett, for unintentionally inspiring the idea, as well as
telling me the original variant of the Bob and Mallory story, and the Django
CSRF Middleware authors, who thought up of this before me. Gareth Heyes
suggested using the frame-breaker option to protect against CSS overlay attacks.
Loading