Security
A rich text editor accepts files and HTML from users. These are the checks PHP HTML Editor makes on the server, where a user cannot switch them off.
Uploads
- Images are identified by their bytes, not their name or the browser's MIME type. The stored file gets the extension of its real type, so a script named
photo.jpgis refused and a PNG named.jpgis stored as.png. - PHP, ASP, HTML, SVG, JavaScript, server configuration files and similar types are never stored, whatever a policy's
Extensionssays. A GIF kept byte for byte (to preserve its animation) is refused if it also contains code. - Image size is checked from the header before the image is decoded, so a small file that would decode to a huge bitmap is refused without using the memory.
- File and folder names are checked against the policy's patterns and against Windows device names; characters such as
;and:never reach the disk. - Every path is resolved inside the storage folder.
..segments are refused and symbolic links are not followed. - Size limits and folder quotas come from the policy.
Permissions
The page chooses the policy from your own login system. The browser can name a category or folder, but the server only accepts categories and storages the policy defines, and every operation checks its own switch (AllowUpload, AllowDeleteFile ...). Nothing in a request can widen a policy.
Cross-site requests
Every upload, gallery and file request must carry a token stored in the visitor's PHP session. Another site cannot read it, so it cannot make a signed-in user's browser upload, rename or delete files.
Photos
JPEG, PNG and WebP uploads are saved again without EXIF, GPS, XMP or ICC data, after applying the camera's orientation. Visitors do not publish where a photo was taken by accident.
HTML
posted() and GetPostedHtml() clean the HTML on the server with an allowlist: scripts, on* event attributes, javascript: and other script URLs, forms, SVG, <object> and <embed> are removed; embedded frames keep a sandbox without access to your site; id and name values that would shadow browser globals are dropped. The policy's black lists remove more. Clean HTML before you save it, and never print $_POST directly.
On the web server
As a second line of defence, configure the upload folders so the web server never runs code from them. The deployment guide has the settings for IIS, Apache and nginx.