# RFC: Session ID without hashing

- Status: Implemented (PHP 7.1)
- Authors: Yasuo Ohgaki yohgaki@ohgaki.net
- Version: 1.2
- Original: https://wiki.php.net/rfc/session-id-without-hashing
- Page: https://externals.io/rfc/session-id-without-hashing
- More for agents: search with https://externals.io/search.md?q={query} · RFCs at https://externals.io/rfc.md · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

## Votes

### Session ID without hashing Re-vote (closed)

Yes: 9 · No: 0

Voters: davey (Yes), dm (Yes), guilhermeblanco (Yes), leigh (Yes), ocramius (Yes), pollita (Yes), sammyk (Yes), stas (Yes), yohgaki (Yes)

### Session ID without hashing Re-vote: INI option (closed)

Use new defaults (BC break): 3 · Use compatible defaults (No BC break): 7

Voters: davey (Use compatible defaults (No BC break)), derick (Use compatible defaults (No BC break)), dm (Use compatible defaults (No BC break)), guilhermeblanco (Use new defaults (BC break)), leigh (Use compatible defaults (No BC break)), ocramius (Use compatible defaults (No BC break)), pollita (Use compatible defaults (No BC break)), sammyk (Use new defaults (BC break)), stas (Use compatible defaults (No BC break)), yohgaki (Use new defaults (BC break))

## Discussions on the mailing list

- [\[RFC\]\[DISCUSSION\] Session ID without hashing](https://externals.io/message/92122.md) — started on 2016-04-06, 18 messages
- [\[RFC\]\[VOTE\] Session ID without hashing](https://externals.io/message/94356.md) — started on 2016-07-02, 48 messages
- [\[RFC\]\[VOTE\] Session ID without hashing - Reopened](https://externals.io/message/94664.md) — started on 2016-07-24, 13 messages
- [\[RFC\]\[VOTE\] Session ID without hashing - Vote reopened and restarted](https://externals.io/message/94703.md) — started on 2016-07-25, 6 messages

---

## Introduction

The objective of this RFC is session module code cleanup, remove unneeded code complexity and redundancy.

- Hash function is not required to generate session ID with CSPRNG.
- Hash function removal results in less number of INI config.

NOTE: It is meaningless applying hash to CS safe random bytes.

Since PHP 7, there is php\_random\_bytes() function. Session ID generation does not need hashing for secure session ID generation. Session module may simply convert random bytes to readable characters.

As a bonus, simple session generation performance increased 2X or more.

- w/ Patch: Requests per second: 2278.59 \[#/sec\] (mean)
- w/o Patch: Requests per second: 899.36 \[#/sec\] (mean)

## Proposal

Use php\_random\_bytes() generated binary random value directly and convert it to session ID by using session internal bin\_to\_readable() function.

Remove hash and RNG related codes and settings from session module.

- session.hash\_function
- session.hash\_bits\_per\_character
- session.entropy\_file
- session.entropy\_length

Add new config for session ID generation.

- session.sid\_length (Session ID string length. Default: 48 or 32)
- session.sid\_bits\_per\_character (Outstanding bits per char. Default: 5 or 4)

Default INI setting is vote option. session.sid\_length=48 and session.sid\_bits\_per\_character=5 is stronger, but BC. session.sid\_length=32 and session.sid\_bits\_per\_character=4 is weaker, but no BC.

NOTE: New session ID is far less likely to have collisions. Even if system has broken CSPRNG, session module has session ID collision detection already.

Min/max length of session ID: 22 - 256 (22 is the same length as MD5 hash with\_hash\_bits\_per\_chars=6)

## Discussions

### Exposing PRNG state has risk

If PRNG has vulnerability that generates predictable value, exposing raw PRNG state helps attackers. Although, this is unlikely with modern PRNGs, but risk is there.

To mitigate risk, additional bytes (+60 bytes) are read from PRNG. Additional bytes should be good enough for predictable session ID with broken PRNG implementation. Those who are concerned PRNG quality, you may choose new INI defaults. Those who are comfortable with PRNG quality and value compatibility, you may choose compatible(old) INI defaults.

## Backward Incompatible Changes

None, when compatible default is chosen

- session.sid\_length=32
- session.sid\_bits\_per\_character=4

If non-compatible default is chosen, session.sid\_length, session.sid\_bits\_per\_character may set to compatible value.

- session.sid\_length=48
- session.sid\_bits\_per\_character=5

## Proposed PHP Version(s)

PHP 7.1

## RFC Impact

### To SAPIs

None

### To Existing Extensions

Session module

### To Opcache

None

### New Constants

None

### php.ini Defaults

hardcoded default and php.ini-\* default values are the same. This is voting option.

- session.sid\_length (Session ID string length. Default: 48 or 32)
- session.sid\_bits\_per\_character (Outstanding bits per char. Default: 5 or 4)

## Open Issues

None

## Unaffected PHP Functionality

3rd party and user save handlers are unaffected.

## Future Scope

## Vote

This project requires 2/3 majority.

**Vote: Session ID without hashing Re-vote** — Yes: 9 · No: 0 (closed)

Please select preferred default options. If number of votes are even, compatible(No BC break) options are used.

- New defaults: session.sid\_length=48, session.sid\_bits\_per\_character=5 (240 bits session ID. BC break)
- Compatible defaults: session.sid\_length=32, session.sid\_bits\_per\_character=4 (128 bits session ID. No BC break)

**Vote: Session ID without hashing Re-vote: INI option** — Use new defaults (BC break): 3 · Use compatible defaults (No BC break): 7 (closed)

- 2nd Vote starts 2016-07-24 and ends 2015-08-02 23:59:59 UTC
- 1st Vote starts 2016-07-02 and ends 2016-07-11

## Patches and Tests

- <https://github.com/php/php-src/pull/1850>

## Implementation

Due to the default value used in php.ini-development/production, INI settings in those files are set to

- session.sid\_length=26
- session.sid\_bits\_per\_character=5

This matches session.hash\_func=0 and session.hash\_bits\_per\_character=5 used since PHP 5.3.

1. the version(s) it was merged to PHP 7.1
2. a link to the git commit(s) 
    1. <http://git.php.net/?p=php-src.git;a=commitdiff;h=3467526a65bfb15eaf9ec49a0b5673b84e26bca4>
3. a link to the PHP manual entry: 
    1. [http://svn.php.net/viewvc?view=revision&amp;revision=339678](http://svn.php.net/viewvc?view=revision&revision=339678)
    2. [http://svn.php.net/viewvc?view=revision&amp;revision=339776](http://svn.php.net/viewvc?view=revision&revision=339776)

## References

- [RFC Enable session.use\_strict\_mode by default.](https://externals.io/rfc/session-use-strict-mode)

## Rejected Features
