Skip to content

Commit f8e76c3

Browse files
authored
Add getFullPageHtml() (#14)
`getFullPageHtml()` doesn't remove HEAD & BODY and preserve inline styles while still sanitizing what it's supposed to be sanitized.
2 parents fd2fbe0 + 3e5a0ec commit f8e76c3

File tree

3 files changed

+45
-12
lines changed

3 files changed

+45
-12
lines changed

README.md

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ $phpInfo = new \Spaze\PhpInfo\PhpInfo();
88
$html = $phpInfo->getHtml();
99
```
1010

11-
`$html` will contain `phpinfo()` output, wrapped in `<div id="phpinfo">` & `</div>`.
11+
## `getHtml()`
12+
The `getHtml()` method returns the `phpinfo()` output, without the HTML `head` and `body` elements, wrapped in `<div id="phpinfo">` & `</div>`.
1213

1314
All inline CSS will be "externalized" to CSS classes, you can load `assets/info.css` to get the colors back.
1415

@@ -17,8 +18,20 @@ An example usage with Nette Framework (can be used with other frameworks or stan
1718
$this->template->phpinfo = Html::el()->setHtml($this->phpInfo->getHtml());
1819
```
1920

21+
Please note that this will also remove the HTML `head` element which contains `meta name="ROBOTS"` tag preventing search engines and other bots indexing the `phpinfo()` output.
22+
You have to add it back somehow, for example by rendering the `getHtml()` output in your own layout which includes the `head` element with the `meta name="ROBOTS"` tag.
23+
In general, `phpinfo()` output should be accessible only for authenticated users.
24+
25+
## `getFullPageHtml()`
26+
Sometimes, you may want to display the classic `phpinfo()` output, with the original HTML `head` and `body` elements, `meta name="ROBOTS"` tag, inline styles etc.,
27+
but still with the sensitive info sanitized (see below). In that case, you may use `getFullPageHtml()`:
28+
```php
29+
$phpInfo = new \Spaze\PhpInfo\PhpInfo();
30+
echo $phpInfo->getFullPageHtml();
31+
```
32+
2033
## Sanitization
21-
By default, session id (as returned by `session_id()` if session is started, or as stored in `$_COOKIE[session_name()]` if not) will be sanitized and replaced by `[***]` in the output.
34+
By default, session id will be automatically determined and replaced by `[***]` in the output.
2235
This is to prevent some session hijacking attacks that would read the session id from the cookie value reflected in the `phpinfo()` output
2336
(see my [blog post](https://www.michalspacek.com/stealing-session-ids-with-phpinfo-and-how-to-stop-it) describing the attack, `HttpOnly` bypasses, and the solution).
2437
You can disable the sanitization by calling `doNotSanitizeSessionId()` but it's totally not recommended. Do not disable that. Please.
@@ -32,30 +45,30 @@ If found, the string in `$sanitize` will be replaced with the string `$with`, if
3245
Some of the values in `phpinfo()` output are printed URL-encoded, so the `$sanitize` value will also be searched URL-encoded automatically.
3346
This means that both `foo,bar` and `foo%2Cbar` would be replaced.
3447

35-
## Sanitizing arbitrary strings
36-
If you have your `phpinfo()` output (or anything really) in a string, you can use the sanitizer standalone, for example:
37-
```php
38-
$sanitizer = new \Spaze\PhpInfo\SensitiveValueSanitizer();
39-
$string = $sanitizer->addSanitization('🍍', '🍌')->sanitize('🍍🍕');
40-
```
41-
4248
The sanitizer will try to determine the session id and sanitize it automatically, you can (but shouldn't) disable it with `doNotSanitizeSessionId()`.
4349

44-
The following values will be automatically used as the session id:
50+
The following values will be used when determining the session id:
4551
1. `session_id()` output if not `false`
4652
2. `$_COOKIE[session_name()]` if it's a string
4753

4854
However, it is not recommended to rely solely on the automated way, because for example you may set the session name somewhere in a custom service,
4955
and it may not be available for the sanitizer to use. I'd rather suggest you configure the sanitization manually:
5056
```php
51-
$sanitizer->addSanitization($this->sessionHandler->getId(), '[***]'); // where $this->sessionHandler is your custom service for example
57+
$phpInfo->addSanitization($this->sessionHandler->getId(), '[***]'); // where $this->sessionHandler is your custom service for example
5258
```
5359
or
5460
```php
55-
$sanitizer->addSanitization($_COOKIE['MYSESSID'], '[***]'); // where MYSESSID is your session name
61+
$phpInfo->addSanitization($_COOKIE['MYSESSID'], '[***]'); // where MYSESSID is your session name
5662
```
5763
or something like that.
5864

65+
## Sanitizing arbitrary strings
66+
If you have your `phpinfo()` output (or anything really) in a string, you can use the sanitizer standalone, for example:
67+
```php
68+
$sanitizer = new \Spaze\PhpInfo\SensitiveValueSanitizer();
69+
$string = $sanitizer->addSanitization('🍍', '🍌')->sanitize('🍍🍕');
70+
```
71+
5972
You can then pass the configured sanitizer to `PhpInfo` class which will then use your configuration for sanitizing the `phpinfo()` output too:
6073
```php
6174
$phpInfo = new \Spaze\PhpInfo\PhpInfo($sanitizer);

src/PhpInfo.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,16 @@ public function getHtml(): string
2828
}
2929

3030

31+
public function getFullPageHtml(): string
32+
{
33+
$error = 'Cannot get phpinfo() output';
34+
ob_start();
35+
phpinfo();
36+
$info = ob_get_clean() ?: $error;
37+
return $this->sanitizer->sanitize($info);
38+
}
39+
40+
3141
/**
3242
* WARNING: Not recommended, disabling session id sanitization may allow
3343
* session stealing attacks that read the cookie from the output of phpinfo().

tests/PhpInfoTest.phpt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,16 @@ class PhpInfoTest extends TestCase
4343
}
4444

4545

46+
public function testGetFullPageHtml(): void
47+
{
48+
$html = (new PhpInfo())->getFullPageHtml();
49+
Assert::notContains('<div id="phpinfo">', $html);
50+
Assert::contains('disable_functions', $html);
51+
Assert::notContains('class="color-', $html);
52+
Assert::contains('style="color: #', $html);
53+
}
54+
55+
4656
public function testGetHtmlSessionIdSanitization(): void
4757
{
4858
$html = (new PhpInfo())->getHtml();

0 commit comments

Comments
 (0)