I. Introduction
How did I mention the XSS error that my site was hacked by? Specifically, I was attacked by hacker by Stored XSS error. I would like to explain more specifically about this XSS error.
Stored XSS: a form of attack that hackers directly insert malicious code into the database of the website. This type of attack occurs when the data that is sent to the server is not thoroughly tested but stored directly into the database. When users access this site, malicious scripts will be executed in conjunction with the process of loading the website.
In PHP, there is a function called strip_tags
, which removes html characters from a string.
For example you have a string containing html tags, now you need to remove it from this string. You can do the following:
1 2 3 4 5 6 7 8 9 10 11 12 | <span class="token php language-php"><span class="token delimiter important"><?php</span> <span class="token variable">$text</span> <span class="token operator">=</span> <span class="token single-quoted-string string">'<p>Test paragraph.</p><!-- Comment --> <a href="#fragment">Other text</a>'</span> <span class="token punctuation">;</span> <span class="token keyword">echo</span> <span class="token function">strip_tags</span> <span class="token punctuation">(</span> <span class="token variable">$text</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">echo</span> <span class="token double-quoted-string string">"n"</span> <span class="token punctuation">;</span> <span class="token comment">// Allow <p> and <a></span> <span class="token keyword">echo</span> <span class="token function">strip_tags</span> <span class="token punctuation">(</span> <span class="token variable">$text</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'<p><a>'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// as of PHP 7.4.0 the line above can be written as:</span> <span class="token comment">// echo strip_tags($text, ['p', 'a']);</span> <span class="token delimiter important">?></span></span> |
And we get the desired result:
1 2 | Test paragraph. Other text |
<p>Test paragraph.</p> <a href="#fragment">Other text</a>
Although strip_tags
can remove html characters for our data, it only deletes certain tags. Each time you call the function, you must specify the tag you want to delete. So the solution here is to use the HTML Purifier.
II. main content
Install the HTML Purifier package
HTML Purifier is available in packagist.org . If you are using composer to manage dependencies. To install the package, execute the following command:
1 2 | $ composer require ezyang/htmlpurifier |
After successfully installing the package will be added in composer.json.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <span class="token property">"require"</span> <span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">"php"</span> <span class="token operator">:</span> <span class="token string">"^7.2"</span> <span class="token punctuation">,</span> <span class="token property">"doctrine/dbal"</span> <span class="token operator">:</span> <span class="token string">"^2.10"</span> <span class="token punctuation">,</span> <span class="token property">"ezyang/htmlpurifier"</span> <span class="token operator">:</span> <span class="token string">"^4.12"</span> <span class="token punctuation">,</span> <span class="token property">"facade/ignition"</span> <span class="token operator">:</span> <span class="token string">"^1.4"</span> <span class="token punctuation">,</span> <span class="token property">"fideloper/proxy"</span> <span class="token operator">:</span> <span class="token string">"^4.0"</span> <span class="token punctuation">,</span> <span class="token property">"intervention/image"</span> <span class="token operator">:</span> <span class="token string">"^2.5"</span> <span class="token punctuation">,</span> <span class="token property">"laravel/framework"</span> <span class="token operator">:</span> <span class="token string">"^6.8"</span> <span class="token punctuation">,</span> <span class="token property">"laravel/tinker"</span> <span class="token operator">:</span> <span class="token string">"^1.0"</span> <span class="token punctuation">,</span> <span class="token property">"nunomaduro/collision"</span> <span class="token operator">:</span> <span class="token string">"^3.0"</span> <span class="token punctuation">,</span> <span class="token property">"predis/predis"</span> <span class="token operator">:</span> <span class="token string">"^1.1"</span> <span class="token punctuation">,</span> <span class="token property">"rap2hpoutre/laravel-log-viewer"</span> <span class="token operator">:</span> <span class="token string">"^1.3"</span> <span class="token punctuation">,</span> <span class="token property">"sentry/sentry-laravel"</span> <span class="token operator">:</span> <span class="token string">"^1.5"</span> <span class="token punctuation">,</span> <span class="token property">"spatie/laravel-analytics"</span> <span class="token operator">:</span> <span class="token string">"^3.9"</span> <span class="token punctuation">,</span> <span class="token property">"sun-asterisk/laravel-chatwork"</span> <span class="token operator">:</span> <span class="token string">"^0.2.0"</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> |
Use the HTML Purifier package
Create File App Support HTMLPurifier.php to setup config for HTMLPurifier
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | <span class="token php language-php"><span class="token delimiter important"><?php</span> <span class="token keyword">namespace</span> <span class="token package">App Support</span> <span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">HTMLPurifier</span> <span class="token punctuation">{</span> <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token variable">$purifier</span> <span class="token punctuation">;</span> <span class="token comment">/** * @param $value * @return mixed */</span> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">function</span> <span class="token function">clean</span> <span class="token punctuation">(</span> <span class="token variable">$value</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> self <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">getPurifier</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">purify</span> <span class="token punctuation">(</span> <span class="token variable">$value</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * @return HTMLPurifier */</span> <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">function</span> <span class="token function">getPurifier</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token function">is_null</span> <span class="token punctuation">(</span> self <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token variable">$purifier</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">//Find full HTML5 config : https://github.com/kennberg/php-htmlpurfier-html5</span> <span class="token variable">$config</span> <span class="token operator">=</span> <span class="token package">HTMLPurifier_Config</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">createDefault</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$config</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">set</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'HTML.Doctype'</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'HTML 4.01 Transitional'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$config</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">set</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'HTML.SafeIframe'</span> <span class="token punctuation">,</span> <span class="token boolean">true</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$config</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">set</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'Cache.SerializerPath'</span> <span class="token punctuation">,</span> <span class="token function">storage_path</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token single-quoted-string string">'/app/purifier'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$config</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">set</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'Cache.SerializerPermissions'</span> <span class="token punctuation">,</span> <span class="token number">777</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$def</span> <span class="token operator">=</span> <span class="token variable">$config</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">getHTMLDefinition</span> <span class="token punctuation">(</span> <span class="token boolean">true</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$def</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">addElement</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'figure'</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'Block'</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'Flow'</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'Common'</span> <span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token single-quoted-string string">'class'</span> <span class="token punctuation">]</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$def</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">addElement</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'oembed'</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'Block'</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'Flow'</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'Common'</span> <span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token single-quoted-string string">'url'</span> <span class="token punctuation">]</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$def</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">addAttribute</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'oembed'</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'url'</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'Text'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> self <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token variable">$purifier</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name"> HTMLPurifier</span> <span class="token punctuation">(</span> <span class="token variable">$config</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> self <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token variable">$purifier</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </span> |
With HTMLPurifier you do not need to fill the list of html tags anymore, instead we whitelist the attributes only such as class, url, … very convenient, right?
And at the store data we want to use just call it out
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <span class="token php language-php"><span class="token delimiter important"><?php</span> <span class="token keyword">use</span> <span class="token package">App Models Comment</span> <span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">App Support HTMLPurifier</span> <span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">Illuminate Http Request</span> <span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">App Http Controllers Controller</span> <span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">CommentController</span> extend <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">store</span> <span class="token punctuation">(</span> Request <span class="token variable">$request</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$data</span> <span class="token operator">=</span> HTMLPurifier <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">clean</span> <span class="token punctuation">(</span> <span class="token variable">$request</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">data</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$comment</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">create</span> <span class="token punctuation">(</span> <span class="token variable">$data</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">return</span> response <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">json</span> <span class="token punctuation">(</span> <span class="token punctuation">[</span> <span class="token single-quoted-string string">'message'</span> <span class="token operator">=</span> <span class="token operator">></span> 'Save a <span class="token keyword">new</span> <span class="token class-name">comment</span> successfully <span class="token punctuation">]</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </span> |
With HTMLPurifier the unnecessary html tags have been removed and XSS attacks are somewhat prevented.
Demo
III. Conclusion
HTML Purifier is an effective packge for XSS prevention solutions. Protect your site to the best, providing the most effective user experience. This is just one of many packages in countless solutions to prevent and prevent XSS. Look forward to the suggestions from everyone.