www/robots.txt
build.properties
dist/
+/vendor/
+2021-11-26 Christian Weiske <cweiske@cweiske.de>
+
+ * Fix open redirect security issue (CWE-601).
+ You have to white-list allowed default URLs now.
+ * Add support for .svg source files
+ * Version 0.3.0
+
+2012-08-27 Christian Weiske <cweiske@bogo>
+
+ * Add support for OpenIDs
+ * Version 0.2.0
+
2012-08-17 Christian Weiske <cweiske@cweiske.de>
* Version 0.1.0
Features:
-- Delivers images for email addresses
+- Delivers images for email addresses and OpenIDs
- Very easy to setup.
- No graphics processing is done on the server, keeping the CPU load low.
All avatar images get pre-generated for a set of sizes
1. Put images in ``raw/`` folder.
Name has to be email address + image file extension, for example
``foo@example.org.png``.
- Surrogator supports ``.png`` and ``.jpg``.
+ Surrogator supports ``.png``, ``.jpg`` and ``svg`` files.
+
+ For OpenIDs, use the url-encoded URL + extension as filename, for example
+ replace ``/`` with ``%2F``.
+ The filename for ``http://example.org/~foo`` would be
+ ``http:%2F%2Fexample.org%2F~foo.jpg``.
+
2. Run ``php surrogator.php``.
The small files get generated.
3. You will get more information with ``-v``
when the raw file is newer than the "square" file in the var folder.
You can force the update with ``--force``.
+Note: PHP imagick extension is required for ``svg`` files.
+
====
Test
-->
<property file="build.properties" />
- <property name="version-m" value="0.1" />
- <property name="version" value="0.1.0" />
+ <property name="version-m" value="0.3" />
+ <property name="version" value="0.3.0" />
<property name="stability" value="alpha" />
<property name="zipfile" value="${phing.project.name}-${version}.tar.bz2" />
<property name="distfile" value="dist/${zipfile}" />
--- /dev/null
+{
+ "name": "cweiske/surrogator",
+ "description": "Libravatar compatible avatar image server",
+ "license": "AGPL-3.0-only",
+ "require": {
+ "ext-gd": "*",
+ "ext-imagick": "*"
+ }
+}
--- /dev/null
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+ "This file is @generated automatically"
+ ],
+ "content-hash": "c94e11a46a1283a678a79c9807c2b641",
+ "packages": [],
+ "packages-dev": [],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": [],
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": {
+ "ext-gd": "*",
+ "ext-imagick": "*"
+ },
+ "platform-dev": [],
+ "plugin-api-version": "2.3.0"
+}
* to true, the images will always be regenerated.
*/
$forceUpdate = false;
+
+/**
+ * URL prefixes that may be used as "default" parameter.
+ *
+ * Taken from https://git.linux-kernel.at/oliver/ivatar/-/blob/master/config.py
+ */
+$trustedDefaultUrls = [
+ 'http://gravatar.com/avatar/',
+ 'http://www.planet-libre.org/themes/planetlibre/images/',
+ 'https://avatars.dicebear.com/api/',
+ 'https://badges.fedoraproject.org/static/img/',
+ 'https://gravatar.com/avatar/',
+ 'https://secure.gravatar.com/avatar/',
+ 'https://ui-avatars.com/api/',
+ 'https://www.azuracast.com/img/',
+];
?>
} else {
$fileInfos = new \RegexIterator(
new \DirectoryIterator($rawDir),
- '#^.+\.(png|jpg)$#'
+ '#^.+\.(png|jpg|svg|svgz)$#'
);
}
foreach ($fileInfos as $fileInfo) {
*/
function getHashes($fileName)
{
+ //OpenIDs have their slashes "/" url-encoded
+ $fileName = rawurldecode($fileName);
+
$fileNameNoExt = substr($fileName, 0, -strlen(strrpos($fileName, '.')) - 2);
$emailAddress = trim(strtolower($fileNameNoExt));
$imgOrig = imagecreatefrompng($origPath);
} else if ($ext == 'jpg' || $ext == 'jpeg') {
$imgOrig = imagecreatefromjpeg($origPath);
+ } else if ($ext == 'svg' || $ext == 'svgz') {
+ $imagickImg = new \Imagick();
+ $imagickImg->setBackgroundColor(new \ImagickPixel('transparent'));
+ $imagickImg->readImage($origPath);
+ $imagickImg->setImageFormat('png32');
+ $imgOrig = imagecreatefromstring($imagickImg->getImageBlob());
} else {
//unsupported format
+ logErr('Unsupported image format: ' . $origPath);
return false;
}
//url
$defaultMode = 'redirect';
$default = $_GET['default'];
- //FIXME: validate?
+
+ $allowed = false;
+ foreach ($trustedDefaultUrls ?? [] as $urlPrefix) {
+ if (substr($default, 0, strlen($urlPrefix)) == $urlPrefix) {
+ $allowed = true;
+ break;
+ }
+ }
+ if (!$allowed) {
+ header('X-Info: default parameter URL not allowed');
+ $defaultMode = 'local';
+ $default = 'default.png';
+ }
}
}
header('Content-Length:' . $stat['size']);
readfile($imgFile);
-?>
\ No newline at end of file
+?>