From a64597ade339bdb7ed87ff57726404bfdd5f2c34 Mon Sep 17 00:00:00 2001 From: Cornelius <cornelius.amzar@bsz-bw.de> Date: Mon, 2 Mar 2020 21:50:44 +0100 Subject: [PATCH] Secured UrlShortener against tampering by using hashes instead of ids (#1549) - Note that the database upgrade tool must be run after loading this commit to ensure that the shortlinks table's hash column is correctly populated. (cherry picked from commit 7732da3c0f0243061fdaf90485d749d122d1ec8a) --- config/vufind/BrowZine.ini | 2 +- config/vufind/config.ini | 229 +++++++++---------------------------- 2 files changed, 57 insertions(+), 174 deletions(-) diff --git a/config/vufind/BrowZine.ini b/config/vufind/BrowZine.ini index 50aa8795201..e2ff9be891e 100644 --- a/config/vufind/BrowZine.ini +++ b/config/vufind/BrowZine.ini @@ -3,7 +3,7 @@ ; https://thirdiron.atlassian.net/wiki/spaces/BrowZineAPIDocs/overview [General] ; BrowZine-issued access token for API -access_token = "Passwordxx-xxxx-xxxx-xxxx-PasswordPassword" +access_token = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" ; The ID number of your library (found in your BrowZine public access URL) library_id = "yyy" diff --git a/config/vufind/config.ini b/config/vufind/config.ini index 15357a69631..19ceddd9bdb 100644 --- a/config/vufind/config.ini +++ b/config/vufind/config.ini @@ -624,6 +624,20 @@ sms = enabled ; store its path in the database (default "none"). url_shortener = none +; Which method to use for generating the short link key. Options: +; - base62: Base62-encode the database row ID (insecure, but makes very short URLs) +; - md5: Create a salted MD5 hash of the URL (DEFAULT: more private, but also longer) +; ...or any hash algorithm supported by PHP's hash() function. +url_shortener_key_type = md5 + +; Which redirect mechanism to use when shortlinks are resolved. +; threshold:1000 (default) : If the URL is shorter than the given size, HTTP is used, else HTML. +; html : HTML meta redirect after 3 seconds with infobox. +; http : Use HTTP location header for redirects. +; May cause problems if the HTTP header is longer than 8192 bytes +; due to long URL's. +;url_shortener_redirect_method = threshold:1000 + ; This section needs to be changed to match your database connection information [Database] ; Connection string format is [platform]://[username]:[password]@[host]:[port]/[db] @@ -704,25 +718,16 @@ database = mysql://root@localhost/vufind ; Optional: Session ID parameter for SAML2 single logout support. If omitted, single ; logout support is disabled. Note that if SLO support is enabled, Shibboleth session ; ID's are tracked in external_session table which may need to be cleaned up with the -; util/expire_external_sessions command line utility. See +; expire_session_mappings command line utility. See ; https://vufind.org/wiki/configuration:shibboleth for more information on how ; to configure the single logout support. ;session_id = Shib-Session-ID -; Check for expired session - user is automatically logged out when Shibboleth -; session is not present (default = true if unset); note that expiration check -; also requires session_id to be set above. -;checkExpiredSession = false ; Optional: you may set attribute names and values to be used as a filter; ; users will only be logged into VuFind if they match these filters. ;userattribute_1 = entitlement ;userattribute_value_1 = urn:mace:dir:entitlement:common-lib-terms ;userattribute_2 = unscoped-affiliation ;userattribute_value_2 = member -; Set to true when shibboleth attributes must be read from headers instead of -; environment variables - for example if you use proxy server and shibboleth is -; running on proxy side. In that case you should protect against header spoofing: -; see https://wiki.shibboleth.net/confluence/display/SP3/SpoofChecking for details -;use_headers = false ; Required: the attribute Shibboleth uses to uniquely identify users. ;username = persistent-id ; Required: Shibboleth login URL. @@ -744,9 +749,6 @@ database = mysql://root@localhost/vufind ;college = HTTP_COLLEGE ;major = HTTP_MAJOR ;home_library = HTTP_HOME_LIBRARY -; Enable if you want to override mapping or required attributes for specific IdP -; in Shibboleth.ini -;allow_configuration_override = true ; CAS is optional. This section only needs to exist if the ; Authentication Method is set to CAS. @@ -810,6 +812,9 @@ database = mysql://root@localhost/vufind ; External Content is Optional. ; To use multiple, separate with a comma. Priority will be given by the order listed ; Account id is separated with a colon, if no id is used then no colon is necessary +; For Amazon, use your 20-character access key in the coverimages and reviews values; +; you must also provide your 40-character secret key in the amazonsecret value and +; your associate ID in the amazonassociate value. ; ; IMPORTANT: Review content providers' terms of service before turning them on. ; Terms may change, and not all content sources are appropriate for all @@ -836,11 +841,9 @@ database = mysql://root@localhost/vufind ; coversize setting to false: ;coversize = false -; You can select Syndetics, LibraryThing, Summon, Booksite, OpenLibrary, -; Contentcafe, Buchhandel.de, Google Books, BrowZine, ObalkyKnih and/or LocalFile. +; You can select Syndetics, LibraryThing, Summon, Amazon, Booksite, OpenLibrary, +; Contentcafe, Buchhandel.de, Google Books, BrowZine and/or LocalFile. ; Note: BrowZine requires you to have BrowZine.ini configured appropriately. -; Note: ObalkyKnih could be configured in obalkyknih.ini file. You should also -; add API URLs to img-src directive in contentsecuritypolicy.ini ; Note: Summon service takes a Serials Solutions client key, NOT Summon API key! ; For LocalFile:PathToFile, you may use a combination of directory path information ; and tokens for filename and image type. If you have multiple directories @@ -859,7 +862,7 @@ database = mysql://root@localhost/vufind ; %vufind-home% - The VUFIND_HOME environment variable ; %vufind-local-dir% - The VUFIND_LOCAL_DIR environment variable ; Example: LocalFile:%vufind-local-dir%/path/to/file/%size%/issn/%issn%.%anyimage% -;coverimages = Syndetics:MySyndeticsId,Booksite,LibraryThing:MyLibraryThingId,Google,ObalkyKnih,OpenLibrary,Summon:MySerialsSolutionsClientKey,Contentcafe:MyContentCafeID,BrowZine,LocalFile:PathToFile +;coverimages = Syndetics:MySyndeticsId,Amazon:MyAccessKeyId,Booksite,LibraryThing:MyLibraryThingId,Google,OpenLibrary,Summon:MySerialsSolutionsClientKey,Contentcafe:MyContentCafeID,BrowZine,LocalFile:PathToFile ; This setting controls which services will have images cached on your local disk. ; Set to true to cache all applicable services. Set to false to disable caching. Set @@ -875,16 +878,6 @@ coverimagesCache = true ; "/.*/" to turn on caching for all proxied images. ;coverproxyCache[] = "/.*\.?mylibrary\.edu/" -; This setting controls how cover image URLs are loaded. They could be loaded as -; part of main request, or asynchronously. Asynchronous loading is disabled by -; default; to enable it, just uncomment the line below. -;ajaxcovers = true - -; When ajaxcovers is set to true, this setting controls whether the AJAX Handler -; GetRecordCover renders a fallback template (record/coverReplacement.phtml) in case -; no cover image could be loaded. -;useCoverFallbacksOnFail = false - ; These settings control the image to display when no book cover is available. ; If makeDynamicCovers is not false and the GD library is installed, VuFind will draw ; cover images on the fly. See [DynamicCovers] below for more settings. If set to @@ -896,12 +889,13 @@ coverimagesCache = true ; path relative to the base of your theme directory for a static image to display. noCoverAvailableImage = images/noCover2.gif -; You can select from Syndetics, SyndeticsPlus, Booksite and/or the Guardian +; You can select from Syndetics, SyndeticsPlus, Amazon Editorial, Amazon, Booksite +; and/or the Guardian ; Note: If the API key is omitted, e.g. "Guardian:", only the review title, byline, ; Guardian logo and a link to the full Guardian page will be displayed ; Note: The Guardian API changed in 2014; if you signed up before that date, you ; may need to obtain a new API key for continued access. -;reviews = Syndetics:MySyndeticsId,SyndeticsPlus:MySyndeticsID,Booksite,Guardian:MyGuardianKeyId +;reviews = Syndetics:MySyndeticsId,SyndeticsPlus:MySyndeticsID,AmazonEditorial:MyAccessKeyId,Amazon:MyAccessKeyId,Booksite,Guardian:MyGuardianKeyId ; You can select from Syndetics or SyndeticsPlus ;excerpts = Syndetics:MySyndeticsId,SyndeticsPlus:MySyndeticsId @@ -932,6 +926,15 @@ noCoverAvailableImage = images/noCover2.gif ; heap size settings. For details, see: https://vufind.org/jira/browse/VUFIND-630 authors = Wikipedia +; You can look up your secret key by logging into http://aws.amazon.com and clicking +; "Access Identifiers" under "Your Account". +;amazonsecret = MyAmazonSecretKey + +; You can sign up for an associate ID by logging into +; https://affiliate-program.amazon.com . Please make sure your instance of VuFind +; complies with Amazon's agreements before enabling this feature. +;amazonassociate = MyAmazonAssociateID + ; You can select from Google, OpenLibrary, HathiTrust. You should consult ; https://developers.google.com/books/branding before using Google Book Search. ;previews = Google,OpenLibrary,HathiTrust @@ -1155,17 +1158,10 @@ url = "https://api.booksite.com" [DOI] ; This setting controls whether or not DOI-based links are enabled, and which ; API is used to fetch the data. Currently supported options: BrowZine (requires -; credentials to be configured in BrowZine.ini), Unpaywall or false (to disable). -; Disabled by default. You may also use a comma-separated list of resolvers if you -; want to try multiple sources. +; credentials to be configured in BrowZine.ini), Unpaywall or false (to disable). Disabled +; by default. ;resolver = BrowZine -; If you use multiple values in the resolver setting above, you can determine how the -; software should behave when multiple resolvers return results for the same DOI. -; You can choose "first" (only return results from the first matching resolver -- -; the default behavior) or "merge" (merge together all results and show them all). -;multi_resolver_mode = first - ;unpaywall_api_url = "https://api.unpaywall.org/v2" ; Unpaywall needs an email adress, see https://unpaywall.org/products/api ;unpaywall_email = "your@email.org" @@ -1206,8 +1202,6 @@ window_settings = "toolbar=no,location=no,directories=no,buttons=no,status=no,me ; If you want to display a graphical link to your link resolver, uncomment the ; settings below. graphic should be a URL; graphic_width and graphic_height ; should be sizes in pixels. -; Note: You will probably will need to add URL of image to img-src setting -; in contentsecuritypolicy.ini file ;graphic = "http://myuniversity.edu/images/findIt.gif" ;graphic_width = 50 ;graphic_height = 20 @@ -1356,59 +1350,8 @@ url = https://www.myendnoteweb.com/EndNoteWeb.html ;host = your.proxy.server ;port = 8000 -; Uncomment one of the following lines to set proxy type to SOCKS 5 or SOCKS 5 with -; name resolution done by proxy. Setting either of these will make VuFind use the -; curl adapter for HTTP requests. +; Uncomment following line to set proxy type to SOCKS 5 ;type = socks5 -;type = socks5_hostname - -; If VuFind is running behind a proxy that uses X-Real-IP/X-Forwarded-For headers, -; you should configure this setting on so that VuFind reports correct user IP -; addresses, and sets permissions appropriately. CONFIGURE THIS WITH CARE! It is -; possible to spoof IP addresses, and configuring this to differentiate between -; legitimate headers from your proxy and spoofed values is critical to protecting -; your content. -; -; The setting should be an ordered, comma-separated list of headers, with optional -; colon-separated modifiers specifying behavior. -; -; Header values can be any keys in PHP's $_SERVER superglobal array; these are -; the most commonly used options: -; - HTTP_X_FORWARDED_FOR -; - HTTP_X_REAL_IP -; -; Supported behaviors (if unspecified, "single" is the default behavior): -; - first (pick the first comma-separated value; e.g. "a" in "a, b, c") -; - last (pick the last comma-separated value; e.g. "c" in "a, b, c") -; - single (enforce single values; completely ignore multi-valued headers) -; -; See also forwarded_ip_filter below for a way to filter out known IP addresses -; of internal network devices before applying first/last/single settings. -; -; When commented out or set to false, only the regular REMOTE_ADDR value will -; be used for IP detection. REMOTE_ADDR will also be used as the default value -; if none of the configured headers are populated. -; -; If you need to implement more nuanced functionality, you can extend or -; override the VuFind\Net\UserIpReader class to implement your own logic. -; -; You can use a header-modifying browser plugin to determine how your proxy -; will respond to spoofing attempts. -; -; See this wiki page for additional notes and comments: -; https://vufind.org/wiki/administration:security#proxies_and_ip_authentication -; -; The example below, if uncommented, will use X-Real-IP if found, and the -; rightmost value of X-Forwarded-For otherwise (resorting to REMOTE_ADDR only -; if no relevant X- headers are found). -;allow_forwarded_ips = "HTTP_X_REAL_IP:single,HTTP_X_FORWARDED_FOR:last" - -; This setting can be used in combination with allow_forwarded_ips to prevent -; known IP addresses of internal proxies and network devices from being reported -; as end user IP addresses. You can repeat the setting for each IP address that -; you wish to exclude. The first/last/single processing parameters used by -; allow_forwarded_ips will be applied AFTER removing addresses filtered here. -;forwarded_ip_filter[] = 1.2.3.4 ; Default HTTP settings can be loaded here. These values will be passed to ; the \Zend\Http\Client's setOptions method. @@ -1422,12 +1365,6 @@ url = https://www.myendnoteweb.com/EndNoteWeb.html ; that you may also need to install CURL and PHP/CURL packages on your server. ;adapter = 'Zend\Http\Client\Adapter\Curl' -; Set curl options if required. See -; https://www.php.net/manual/en/function.curl-setopt.php for available options and -; https://github.com/curl/curl/blob/master/include/curl/curl.h for their numeric -; values. -;curloptions[52] = true - ; Spelling Suggestions ; ; Note: These settings affect the VuFind side of spelling suggestions; you @@ -1500,18 +1437,6 @@ skip_numeric = true ; - Add /slack to the end of your url for Slack-compatible messages ; https://discordapp.com/developers/docs/resources/webhook#execute-slackcompatible-webhook -; You can use Office365 webhooks to send messages to a Microsoft Team channel. -; In the "Connectors" setting on a channel, you can add "Incoming Webhook." This -; will provide a URL that you can paste into the office365_url setting. -; If you are concerned about rate limits, you might also wish to set up the -; VuOwma message aggregator; see https://github.com/FalveyLibraryTechnology/VuOwma -;office365_url = "https://outlook.office.com/webhook/xxx/IncomingWebhook/yyy" -; This setting controls the error levels that will be logged to Office365; if -; commented out, Office365 logging will be disabled -;office365 = alert,error -; This setting controls the title on the messages displayed in Office365: -;office365_title = "VuFind Log" - ; This section can be used to specify a "parent configuration" from which ; the current configuration file will inherit. You can chain multiple ; configurations together if you wish. @@ -1519,7 +1444,7 @@ skip_numeric = true ; Full path to parent configuration file: ;path = /usr/local/vufind/application/config/config.ini ; Path to parent configuration file (relative to the location of this file): -;relative_path = ../parentconfig/config.ini +;relative_path = ../masterconfig/config.ini ; A comma-separated list of config sections from the parent which should be ; completely overwritten by the equivalent sections in this configuration; @@ -1594,10 +1519,6 @@ rtl_langs = "ar,he" ; have a large index! [Browse] result_limit = 100 - -; These settings can be used to turn specific browse types on or off; the order -; of the settings in the configuration below will also control the order of the -; options displayed in the web interface: tag = true ; allow browsing of Tags dewey = false ; allow browsing of Dewey Decimal call numbers lcc = true ; allow browsing of LC call numbers @@ -1606,7 +1527,6 @@ topic = true ; allow browsing of subject headings genre = true ; allow browsing of genre subdivisions region = true ; allow browsing of region subdivisions era = true ; allow browsing of era subdivisions - ; You can use this setting to change the default alphabet provided for browsing: ;alphabet_letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ; Uncomment to sort lists alphabetically (instead of by popularity); note that @@ -1719,15 +1639,6 @@ jump_to_single_search_result = false ; punctuation, but this can be used when ISBD punctuation is absent (e.g. ", "). ;marcPublicationInfoSeparator = " " -; If you have a custom index, you might want to change the field where the full -; MARC record is supposed to be. The field will be checked and ignored, if it is -; not a valid index field or does not exist in the record or index schema. -; If you have multiple fields with MARC content, you may add all of them -; by using a comma sepated list. The first field is the preferred one, if it does not -; exist, the next ones are taken. -; (Default = "fullrecord") -preferredMarcFields = "fullrecord" - ; When displaying publication information from 260/264, this can be set to true ; to make 264 information completely replace 260 information. Default is false, ; which will display information from 260 AND 264 when both fields are populated. @@ -1880,7 +1791,7 @@ treeSearchLimit = 100 ;sender_name = "VuFind Feedback" ; Note: for additional details about stats (including additional notes on Google -; Analytics and Matomo/Piwik), look at the wiki page: +; Analytics and Piwik), look at the wiki page: ; https://vufind.org/wiki/configuration:usage_stats ; Uncomment this section and provide your API key to enable Google Analytics. Be @@ -1891,20 +1802,18 @@ treeSearchLimit = 100 ;apiKey = "mykey" ;universal = false -; The Piwik product has been renamed to Matomo, but for backward compatibility, -; the terminology has not yet been changed in VuFind. Uncomment this section and -; provide your Matomo or Piwik server address and site id to enable Matomo/Piwik -; analytics. Note: VuFind's Matomo/Piwik integration uses several custom variables; -; to take advantage of them, you must reconfigure Matomo/Piwik by switching +; Uncomment this section and provide your Piwik server address and site id to +; enable Piwik analytics. Note: VuFind's Piwik integration uses several custom +; variables; to take advantage of them, you must reconfigure Piwik by switching ; to its root directory and running this command to raise a default limit: ; ./console customvariables:set-max-custom-variables 10 [Piwik] ;url = "http://server.address/piwik/" ;site_id = 1 ; Uncomment the following setting to track additional information about searches -; and displayed records with Matomo/Piwik's custom variables +; and displayed records with Piwik's custom variables ;custom_variables = true -; By default, searches are tracked using the format "Backend|Search Terms." +; By default, Piwik searches are tracked using the format "Backend|Search Terms." ; If you need to differentiate searches coming from multiple VuFind instances using ; a shared site_id, you can set the searchPrefix to add an additional prefix to ; the string, for example "SiteA|Backend|Search Terms." Most users will want to @@ -1956,46 +1865,22 @@ treeSearchLimit = 100 ;EDS = "EBSCO Discovery Service" ; Activate Captcha validation on select forms -; VuFind can use Captcha validation to prevent bots from using certain actions of -; your instance. +; VuFind will use reCaptcha validation to prevent bots from using certain actions of +; your instance. See http://www.google.com/recaptcha for more information on Captcha +; and create keys for your domain. +; You will need to provide a sslcapath in the [Http] section for your Captcha to work. ;[Captcha] -; Valid type values: -; - figlet (generate a text-based message for the user to interpret) -; - image (generate a local image for the user to interpret) -; - recaptcha (use Google's ReCaptcha service) -; If multiple values are given, the user will be able to pick his favorite. -; See below for additional type-specific settings. -;types[] = recaptcha - -; The "forms" setting controls the contexts in which CAPTCHA will be presented. It -; can be either a comma-separated list of forms, or "*" to display CAPTCHA on all -; supported forms. Valid forms values: -; changeEmail, changePassword, email, feedback, newAccount, passwordRecovery, -; sms, userComments +;siteKey = "get your reCaptcha key at" +;secretKey = "https://www.google.com/recaptcha/admin/create" +; Valid theme values: dark, light +;theme = light +; Valid forms values: changePassword, email, feedback, newAccount, passwordRecovery, +; sms, userComments +; Use * for all supported forms ; Note: when "feedback" is active, Captcha can be conditionally disabled on a ; form-by-form basis with the useCaptcha setting in FeedbackForms.yaml. -;forms = * - -; Figlet options, see: -; https://docs.laminas.dev/laminas-captcha/adapters/#laminascaptchafiglet -;figlet_length = 8 - -; Image options, see: -; https://docs.laminas.dev/laminas-captcha/adapters/#laminascaptchaimage -;image_length = 8 -;image_width = 200 -;image_height = 50 -;image_fontSize = 24 -;image_dotNoiseLevel = 100 -;image_lineNoiseLevel = 5 - -; See http://www.google.com/recaptcha for more information on reCAPTCHA and to -; create keys for your domain. Make sure that SSL settings are correct in the -; [Http] section, or your Captcha may not work. -;recaptcha_siteKey = "get your reCaptcha key at" -;recaptcha_secretKey = "https://www.google.com/recaptcha/admin/create" -; Valid theme values: dark, light -;recaptcha_theme = light +;forms = changeEmail, changePassword, email, newAccount, passwordRecovery, sms + ; This section can be used to display default text inside the search boxes, useful ; for instructions. Format: @@ -2034,8 +1919,6 @@ lists_view=full ; Tags may be "enabled" or "disabled" (default = "enabled") ; When disabling tags, don't forget to also turn off tag search in searches.ini. tags = enabled -; User list tags may be "enabled" or "disabled" (default = "disabled") -listTags = disabled ; This controls the maximum length of a single tag; it should correspond with the ; field size in the tags database table. max_tag_length = 64 -- GitLab