Compare commits

...

220 Commits

Author SHA1 Message Date
Michal Čihař
e5f1555e1b Merge tag 'RELEASE_4_0_10_14' into MAINT_4_0_10
Released 4.0.10.14
2017-12-16 13:06:41 +01:00
Tejisav Singh Brar
79f0afbd33 Fixed tracking report: cannot delete a statement (#13567)
Signed-off-by: Tejisav Singh Brar <tejisav@gmail.com>
2017-08-06 07:42:13 -04:00
Isaac Bennetch
9a9a6ab709 Prepare for 4.0.10.20
Signed-off-by: Isaac Bennetch <bennetch@gmail.com>
2017-03-28 20:54:38 -04:00
Isaac Bennetch
83ea1f5e4f Add ChangeLog entries
Signed-off-by: Isaac Bennetch <bennetch@gmail.com>
2017-03-28 20:53:12 -04:00
Michal Čihař
b6ca92cc75 Truncate only long passwords
This avoids problems with certain PHP versions returning false when
first parameter to substr is ''.

Signed-off-by: Michal Čihař <michal@cihar.com>
2017-03-27 16:23:01 +02:00
Michal Čihař
1f859b1b15 Merge pull request #13098 from schoonc/fix-search-new-php-gettext
Fix database search with newer php-gettext
2017-03-20 16:38:13 +01:00
Michal Čihař
ebb97a3960 Remove no longer working test
We no longer directly process value from cookie here, so the test can no
longer work.

Signed-off-by: Michal Čihař <michal@cihar.com>
2017-03-20 16:37:04 +01:00
Сорокин Александр
f9a74deeb6 Fix database search with newer php-gettext
Backport from 4.6.6 (see #12881)

Signed-off-by: Сорокин Александр <ale10059@yandex.ru>
2017-03-18 14:21:36 +03:00
Isaac Bennetch
3d8b97b255 ChangeLog for 4.0.10.19
Signed-off-by: Isaac Bennetch <bennetch@gmail.com>
2017-01-23 12:59:50 -05:00
Michal Čihař
567b27487e Prepare changelog for 4.0.10.19
Signed-off-by: Michal Čihař <michal@cihar.com>
2017-01-21 16:42:07 +01:00
Michal Čihař
4b5f3f9a12 Merge changes from php-gettext 1.0.12
This ensures that parameter to select_string is numeric, avoiding code
injection through it.

Our code is not vulnerable as we do not pass user supplied values to
this function, this fix is included only to be closer to upstream.

Signed-off-by: Michal Čihař <michal@cihar.com>
2017-01-17 13:34:53 +01:00
Michal Čihař
88cc11ab13 Disable setup if configuration already exists
The setup allows to figure out quite a lot about system and network, so
it's safer to block access to it once phpMyAdmin has been configured.

Signed-off-by: Michal Čihař <michal@cihar.com>
2017-01-07 11:00:16 +01:00
Michal Čihař
801485a7f4 Remove setup download/load/delete features
This removes risk of third party manipulating with the configuration as
there was race condition between editing and using the file.

Downloading the file should not be big hassle and this really makes the
whole setup a bit simpler.

Signed-off-by: Michal Čihař <michal@cihar.com>
2017-01-07 10:59:39 +01:00
Michal Čihař
f8ad5bd759 Do not allow arbitrary connection in replication setup without AllowArbitraryServer
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-12-21 11:07:00 +01:00
Michal Čihař
8a0816266c Do not provide fallback to cookie for font size
* This should be already handled by Config class
* Injecting cookie value to CSS could be security risk

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-12-08 11:26:51 +01:00
Michal Čihař
00607e6041 Whitespace cleanup
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-12-08 11:19:12 +01:00
Michal Čihař
3d230b6ab7 Avoid infinite recursion on goto
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-12-08 11:18:51 +01:00
Michal Čihař
7fe97a1f3c Avoid using REQUEST_URI in form action
It's really not necessary here and might cause redirection issues.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-12-08 10:51:48 +01:00
Michal Čihař
afe84645f2 Quote table name for use in regexp
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-12-08 10:30:17 +01:00
Michal Čihař
69b4b5c7f5 Remove wrong changelog entry
This was not yet fixed.

Issue #12481

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-12-01 10:54:31 +01:00
Isaac Bennetch
8783113cec 4.0.10.18 release and ChangeLog
Signed-off-by: Isaac Bennetch <bennetch@gmail.com>
2016-11-24 10:54:44 -05:00
Deven Bansod
6703597772 Handle multiple :p while sanitizing MySQL hosts
Signed-off-by: Deven Bansod <devenbansod.bits@gmail.com>
2016-11-08 10:14:23 +05:30
Deven Bansod
337b38044d Manage new-lines and extra whitespaces properly
Signed-off-by: Deven Bansod <devenbansod.bits@gmail.com>
2016-10-11 10:43:22 +05:30
Deven Bansod
54875fffc1 Manage new-lines and extra whitespaces properly
Signed-off-by: Deven Bansod <devenbansod.bits@gmail.com>
2016-10-11 10:35:47 +05:30
Michal Čihař
be5196ba44 Merge branch 'MAINT_4_0_10-security' of github.com:phpmyadmin/phpmyadmin-security into MAINT_4_0_10-security 2016-10-04 13:18:42 +02:00
Michal Čihař
5e108a340f Correctly parse string length when checking serialized data
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-10-04 13:17:07 +02:00
Deven Bansod
773f126c89 Don't assume the default arg_separator in URL
Respect the value for arg_separator.input too.

Signed-off-by: Deven Bansod <devenbansod.bits@gmail.com>
2016-10-02 10:43:40 +05:30
Michal Čihař
63b7f6c0a9 Use hash_equals when comparing IPv6 allow rules
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-09-02 15:09:29 +02:00
Michal Čihař
af7c589391 Stricter URL validation
- do not use empty() as empty('0') is true
- do not lowercase the strings, use them as they are
- lowercase all domains in our codebase
- do not allow to specify port

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-09-02 15:02:44 +02:00
Michal Čihař
0c3dfd186c Fix possible DOS on too big skip value
- loop only as long as long we have data to skip
- convert skip parameter to integer

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-09-02 13:42:15 +02:00
Michal Čihař
d37abc38da Do not show warning about short blowfish_secret if none is set
With empty blowfish_secret user would always get both warnings...

Fixes #12485

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-08-24 12:04:45 +02:00
Michal Čihař
67700620db Limit maximal number of rows in QBE
User would be lost in them anyway by that count and it prevents DOS.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-08-18 16:55:48 +02:00
Michal Čihař
b2605ebba6 Fix hash validation
- use copy of hash to avoid race condition
- stricter regex to match whole string

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-08-18 11:25:21 +02:00
Michal Čihař
096856c70c Stricter validation of NavigationLogoLink
It now has to be URL including scheme. Otherwise it's not really
possible to validate it for being just http/https.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-08-18 11:18:21 +02:00
Michal Čihař
c2f7a898dd Store copy of hash instead of working on live object
This avoids possible race conditions when doing the checks.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-08-18 11:05:56 +02:00
Michal Čihař
f2add98bd9 Strip path even if openbasedir restrictions apply
This really should not be the case here as what we get here is code
executed by PHP, so it should have already passed openbasedir
restrictions.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-08-18 10:14:01 +02:00
Michal Čihař
6117ad5cef Use hash_equals for checking username
This makes the comparison happen in constant time and makes it
impossible to use it to guess stored usernames.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-08-18 09:39:22 +02:00
Michal Čihař
58245cb1cc Use hash_equals for comparing username in allow/deny rules
The comparison should happen in constant time to avoid possible leak of
usernames in rules.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-08-18 09:15:34 +02:00
Michal Čihař
285e5623b6 Strip null bytes from MySQL username
In old PHP versions this could lead to allow/deny rules bypass.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-08-18 09:10:55 +02:00
Isaac Bennetch
5ba96c8804 Release 4.0.10.17
Signed-off-by: Isaac Bennetch <bennetch@gmail.com>
2016-08-16 16:33:47 -04:00
Michal Čihař
12db0baeae Move hostname sanitization to correct place
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-29 14:10:07 +02:00
Michal Čihař
2922cb7c70 Do not try to wrap output in case response handling is disabled
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-28 10:53:37 +02:00
Michal Čihař
533ffa4942 Add login and token validation to version_check
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-28 10:53:31 +02:00
Michal Čihař
126321da37 Escape string when showing confirmation message
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-28 10:31:30 +02:00
Michal Čihař
b0e66715ba Do not allow to set too long password
We do not accept password longer than 256 chars, so do not accept it on
password change as well.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-26 17:03:00 +02:00
Michal Čihař
262aa8ec73 Fix password change with cookie auth
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-26 17:02:13 +02:00
Michal Čihař
47d00af08a Move generator scripts out of the code
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-26 16:38:30 +02:00
Michal Čihař
eec14404a7 Remove option to show phpinfo() ($cfg['ShowPhpInfo'])
This is really more a PHP debugging feature than anything related to
phpMyAdmin. If user wants to debug, it's as simple a creating file with
one line of php code.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-26 11:03:53 +02:00
Michal Čihař
ac703223e9 Ensure GIS point coordinates are numeric
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-23 10:24:35 +02:00
Michal Čihař
4d15f6b131 Fix random invocation
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-23 09:05:12 +02:00
Michal Čihař
d03954bf9c Enable LOAD DATA LOCAL INFILE only when needed
There is no need to have this feature allowed for normal SQL queries, it
can lead to leaking sensitive files from the web server. It's enough to
enable it only in LDI import plugin, where we control what queries are
executed.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-23 08:59:02 +02:00
Michal Čihař
f261abbdf9 Remove no longer used code
It was used by old charts code to download charts.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-22 16:46:32 +02:00
Michal Čihař
5a28b63f9c Limit maximal numver of fields to 4096
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-22 16:00:23 +02:00
Michal Čihař
ae8693db68 Backport cookie encryption from 4.6 branch
- Use hash_hmac for MAC rather than plain SHA1
- Use different secret for MAC than encryption
- Merge pmaServer and pmaPass cookies
- Document 32 chars length for blowfish_secret

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-22 14:40:02 +02:00
Michal Čihař
85e1d6ec80 Send standard set of HTTP headers on redirect
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-22 12:22:53 +02:00
Michal Čihař
378c3820bf Sanitize filename on SHP import
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-22 11:49:35 +02:00
Michal Čihař
6f8eb0993d Delete temporary file before reporting error
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-22 11:31:09 +02:00
Michal Čihař
e8c5cab3c1 Improve URL filtering in url.php
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-18 16:41:04 +02:00
Michal Čihař
714818f3ad Use https to access phpmyadmin.net
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-18 16:20:34 +02:00
Michal Čihař
ab26a8fe97 Fix exporting multiline comments
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-13 12:13:28 +02:00
Michal Čihař
0f87b73ae2 HML encode embedded JSON data
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-13 11:31:55 +02:00
Michal Čihař
04156efeb0 Ensure widht and height are integers
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-13 10:53:51 +02:00
Michal Čihař
31546255f3 Ensure widht and height are integers
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-13 10:51:53 +02:00
Michal Čihař
09a427b288 Escape HTML markup in transformation wrapper
...in case content type is html.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-13 10:34:19 +02:00
Michal Čihař
8f3ee9f9db Do not use empty MIME type
This will turn on content sniffing in browser leading to unwanted
results.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-13 10:27:43 +02:00
Michal Čihař
56e1350118 Properly handle newlines in SQL comments
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-13 09:58:14 +02:00
Michal Čihař
7f7a8ac467 Do not try to create non existing classes
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-13 09:48:21 +02:00
Michal Čihař
ff88cdbed2 Validate image scaling dimensions
Ensure we pass only integers and they are not too big.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-13 09:39:30 +02:00
Michal Čihař
8ac57b1281 Correctly escape MySQL username in queries
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-12 17:35:56 +02:00
Michal Čihař
fec9b98a22 Ensure page number is integer
Even if somebody decides to change configuration storage structure.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-12 16:49:15 +02:00
Michal Čihař
a3953f88ef Escape suggested database name
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-12 16:40:36 +02:00
Michal Čihař
80c93025a7 Validate serialized data before unserializing
We need only strings, integers or arrays, so there is no need to
unserialize strings containing any complex types.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-12 16:25:20 +02:00
Michal Čihař
8e0918cc41 Sanitize MySQL host name before connecting
It can contain p: prefix which we don't want to honor.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-12 15:10:59 +02:00
Michal Čihař
bdc7436c77 Prefer curl over file_get_contents
Curl is better in SSL certificate verification.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-12 14:32:32 +02:00
Michal Čihař
14fd275811 Use iframe sandbox for rendering HTML in transformation
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-12 14:13:14 +02:00
Michal Čihař
c8297b4718 Use phpseclib's Crypt module to generate encryption keys
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-12 14:02:26 +02:00
Michal Čihař
ab05803a42 Do not allow symlinks in UploadDir
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-12 12:47:35 +02:00
Michal Čihař
41684ff1a1 Hide session error messages to avoid FPD
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-12 12:37:19 +02:00
Michal Čihař
e9a4de70a7 Escape HTML in Mediawiki comments
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-12 12:29:35 +02:00
Michal Čihař
0a4cdc25f1 Use _blank target instead of invalid _new
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-12 11:20:16 +02:00
Michal Čihař
63a5fdaa21 Add rel="noopener noreferrer" to all target="_blank" links
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-12 10:59:38 +02:00
Michal Čihař
a416cbe6c7 Use whitelist rather than blacklist for URL filtering
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-12 10:36:33 +02:00
Madhura Jayaratne
6cbbcdb719 Fix XSS in server_replication.php
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2016-07-12 12:05:07 +10:00
Michal Čihař
dc25189741 Fix syntax error in older PHP versions
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-11 09:36:56 +02:00
Michal Čihař
ee6557a689 Remove debugging code
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-11 09:31:55 +02:00
Michal Čihař
ec2bd5d84c Remove Swekey support
It is buggy and their servers are no longer working.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-11 08:57:21 +02:00
Michal Čihař
4440790902 Make proxy IP parsing aware of multiple proxies
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-11 08:22:32 +02:00
Isaac Bennetch
eb2c702ab2 Add Secure and HttpOnly flags for session cookie setup in examples
Signed-off-by: Isaac Bennetch <bennetch@gmail.com>
2016-07-10 22:30:49 -04:00
Michal Čihař
a9005b20bc Properly escape MySQL status variables
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-10 18:06:25 +02:00
Michal Čihař
cf2e0afdb7 Use https for wiki links
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-09 09:10:57 +02:00
Michal Čihař
95b7b7d6dd Improve cookie encryption
- use MAC to validate content before decryption
- create unique IV for every cookie

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-08 17:54:25 +02:00
Michal Čihař
59e0f3dee4 Properly escape generated XML export
Many fields could contain XML markup, so we need to ensure the generated
XML is valid.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-30 10:59:44 +02:00
Michal Čihař
34a1cebf76 Generate valid PHP code even when table/database name contains PHP markup
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-30 10:26:29 +02:00
Michal Čihař
c6cfb58834 Avoid possible path traversal using MySQL username
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-30 10:04:46 +02:00
Michal Čihař
e46fdb8e5e Sent CSP headers for phpinfo
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-30 09:51:38 +02:00
Michal Čihař
01673e94dd Fix type conversion for numeric values
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-24 12:53:39 +02:00
Isaac Bennetch
83416df64f Release 4.0.10.16
Signed-off-by: Isaac Bennetch <bennetch@gmail.com>
2016-06-23 00:01:11 -04:00
Isaac Bennetch
c3d22bee08 Changelog entries for security release
Signed-off-by: Isaac Bennetch <bennetch@gmail.com>
2016-06-22 13:29:21 -04:00
Michal Čihař
b04150e30e Do not allow javascript: links in transformation
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-22 13:26:03 +02:00
Michal Čihař
b974b56781 Fixed rendering of chart of columns with HTML inside
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-22 13:10:37 +02:00
Michal Čihař
9b6f64b8b9 Properly escape zoom search column type
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-22 11:11:47 +02:00
Michal Čihař
351019c074 Quote delimiter before using preg_replace
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-20 12:13:24 +02:00
Michal Čihař
8c336ba285 Update referrer <meta> to match current standards
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-20 10:46:51 +02:00
Michal Čihař
02971f754f Escape HTML when rendering AJAX error
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-20 10:06:42 +02:00
Michal Čihař
abfd97983a Escape attributes when showing images in javascript
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-20 10:03:40 +02:00
Michal Čihař
e13f9862ef Backport Content-Security-Policy from latest release
This way it will work well on current browsers.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-20 09:44:52 +02:00
Michal Čihař
32875196f9 Add referrer CSP and <meta> tag
This avoids leaking Referer header in modern browsers.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-20 09:38:52 +02:00
Michal Čihař
288efea5b4 Simplify and cleanup transformation plugins
Remove PMA_transformation_global_html_replace which makes the code only
more confusing.

Also add escaping to browse transformations.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-17 16:19:31 +02:00
Michal Čihař
f662d591c5 Escape binary log name
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-17 14:53:31 +02:00
Michal Čihař
975089b8c3 Properly escape translated string
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-17 14:48:05 +02:00
Michal Čihař
78f6c54f1b Add error handling to constructing openid message
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-17 14:33:33 +02:00
Michal Čihař
5fefa51139 Escape error messages from OpenID
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-17 14:29:57 +02:00
Michal Čihař
c795a395ba Improve error handling in OpenID example
- properly check parameter types
- catch all exceptions (eg. network error)

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-17 14:26:05 +02:00
Michal Čihař
c93c82ee9c Fix typo in validator
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-17 10:59:03 +02:00
Michal Čihař
fa7a9b787b Improve error handling in setup in case config dir is not present
We do not show these options in UI, but the scripts should handle it
gracefully.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-17 10:58:53 +02:00
Michal Čihař
96c6a7c0a2 Validate input of validator
We can not trust the input here, so we can expect anything and deal with
missing parameters or invalid values.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-17 10:13:12 +02:00
Michal Čihař
e1eb5e8e89 Fix error reporting on invalid request data
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-17 09:52:12 +02:00
Michal Čihař
8451a7a5d2 Move request conversion to generic code
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-17 09:35:02 +02:00
Michal Čihař
c9faf855a0 Properly convert POST parameters
We can get array instead of single parameter, so handle this gracefully.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-17 09:10:30 +02:00
Michal Čihař
6b52ae4d19 Adjust test expectations to match new code
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-16 08:55:39 +02:00
Michal Čihař
805225a28c Limit number of included scripts in get_scripts.js.php
This avoids potential DOS, the limit is same as we use for generating
the URLs.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-15 18:04:43 +02:00
Madhura Jayaratne
75724a361b Fix #11457 414 Request-URI Too Large
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-15 18:04:16 +02:00
Michal Čihař
bf7379771f Use javascript for redirection to https
The current approach is broken since whitelisting is active in url.php
and also allows potential bbcode injection.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-15 17:48:43 +02:00
Michal Čihař
ee10ed1306 Document changes
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-05-30 09:37:33 +02:00
Michal Čihař
d26422eae5 Pass links from changelog through url.php
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-05-30 09:31:27 +02:00
Michal Čihař
b2054a1834 Allow url.php to be used without valid token
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-05-30 09:28:35 +02:00
Michal Čihař
82fc97b15e Pass external links from setup via url.php
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-05-30 09:23:36 +02:00
Michal Čihař
b19c426726 Extend url whitelist to match master
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-05-30 09:22:25 +02:00
Michal Čihař
27505e1c2d Use url.php even in the setup script
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-05-30 09:19:59 +02:00
Michal Čihař
6f413680b1 Backport URL redirection from later releases
- fixes token leak for browsers which do not change referer on
  Location header
- adds whitelist to avoid redirection to any domain

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-05-23 09:48:53 +02:00
Isaac Bennetch
b1cc43ee7f 4.0.10.15 release
Signed-off-by: Isaac Bennetch <bennetch@gmail.com>
2016-02-29 08:13:06 -05:00
Madhura Jayaratne
fe3be9f4b9 Fix XSS in zoom search
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2016-02-29 12:33:47 +11:00
Madhura Jayaratne
7ddce5e39a Fix XSS in User accounts page
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2016-02-29 11:24:04 +11:00
Michal Čihař
e795141fba Add changes for security issues
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-02-25 13:35:26 +01:00
Michal Čihař
25a632a9f4 Merge pull request #22 from phpmyadmin/json-response
Use correct headers for json data
2016-02-25 12:32:45 +01:00
Michal Čihař
155876b48f Merge pull request #20 from phpmyadmin/xss-host
Urlencode hostname
2016-02-25 11:57:24 +01:00
Michal Čihař
45ecc10d18 Avoid skipping the SSL certificate check in TCPDF
This code is never used in phpMyAdmin, but we fix it just to avoid
potential security reports.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-02-25 10:29:26 +01:00
Michal Čihař
0667ea8ac7 Use correct headers for json data
It was previously not marked as such what could potentially lead to
browsers doing some autodetection.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-02-25 10:23:23 +01:00
Michal Čihař
73c8245a3d Urlencode hostname
This can come from the HTTP header, so we need to be sure to sanitize
it.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-02-25 09:57:29 +01:00
Michal Čihař
b8f1e0f325 Escape SQL query for inline editing
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-02-25 09:13:09 +01:00
Isaac Bennetch
945c58b9d2 Release 4.0.10.14
Signed-off-by: Isaac Bennetch <bennetch@gmail.com>
2016-01-29 09:49:22 -05:00
Isaac Bennetch
f166893777 Release 4.0.10.14
Signed-off-by: Isaac Bennetch <bennetch@gmail.com>
2016-01-28 23:34:57 -05:00
Isaac Bennetch
8b3ac5f5e3 Correct release date
Signed-off-by: Isaac Bennetch <bennetch@gmail.com>
2016-01-28 23:31:39 -05:00
Michal Čihař
04a20d5435 Fix syntax error in disabled test
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 15:10:10 +01:00
Michal Čihař
bf2fde282e Merge pull request #11893 from madhuracj/bug11891
Fix #11891 Error with PMA 4.0.10.13 with PHP 5.2
2016-01-28 15:04:19 +01:00
Michal Čihař
3f9c1680c0 Skip PDO test on PHP 5.2
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 15:03:11 +01:00
Michal Čihař
f9b36a377a Use syntax compatible with older PHP versions
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 14:59:46 +01:00
Michal Čihař
d4447a53fa Include more verbose error message
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 14:57:27 +01:00
Michal Čihař
7ca28f105b Skip not supported test on PHP 5.2
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 14:50:34 +01:00
Michal Čihař
1e5d12abcd Revert "Make test check compatible with PHP 5.2"
This reverts commit 6babab9874.
2016-01-28 14:46:34 +01:00
Michal Čihař
6babab9874 Make test check compatible with PHP 5.2
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 14:43:19 +01:00
Michal Čihař
9b5c64e14d Correctly place expected result
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 14:40:58 +01:00
Michal Čihař
ed9e2b474d Remove non working break
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 14:38:25 +01:00
Michal Čihař
c1377f30a2 Define missing queries in the dummy driver
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 14:33:37 +01:00
Michal Čihař
e167f5ade9 Make the test skip without pdo_mysql
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 14:30:05 +01:00
Michal Čihař
2cc9f56559 Remove mistakenly pasted filename
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 14:19:58 +01:00
Michal Čihař
00c64c6dde Skip tests if ReflectionClass::setAccessible is not available
This is the case on PHP 5.2.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 14:17:37 +01:00
Michal Čihař
16e2f464ff Try to run Travis own phpunit
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 14:12:37 +01:00
Michal Čihař
f1ceadaa46 Run php lint on all files
Also avoid trying to use composer on PHP 5.2, it simply doesn't work
there.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 14:11:40 +01:00
Michal Čihař
10dd46fca4 Use PHP 5.4 for running composer
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 14:04:28 +01:00
Michal Čihař
632380d3d9 Test with PHP 5.2 to ensure we don't again release something broken
Issue #11891

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 14:00:27 +01:00
Madhura Jayaratne
555e73f177 Fix #11891 Error with PMA 4.0.10.13 with PHP 5.2
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2016-01-28 22:08:02 +11:00
Michal Čihař
980ccb6ffb Use changelog from release notes
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 10:09:27 +01:00
Michal Čihař
28b5882b96 Document last release
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 09:30:00 +01:00
Isaac Bennetch
16136ea0ef Increment version for 4.0.10.13 release
Signed-off-by: Isaac Bennetch <bennetch@gmail.com>
2016-01-27 21:30:00 -05:00
Michal Čihař
5b79467245 Enable localization before redirect
This is needed in case of IIS which needs full HTML response.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-27 08:55:07 +01:00
Michal Čihař
25738352df Fallback to default collation connection
If user supplied wrong string we should gracefully fallback.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-26 15:05:42 +01:00
Michal Čihař
7056ca9458 Do not process subforms with PMA_MINIMUM_COMMON
In such case needed infrastructure is not loaded, so related code won't
work anyway.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-26 14:34:01 +01:00
Michal Čihař
215f4a8ebe Can not use PMA_fatalError when including fails
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-26 14:30:08 +01:00
Michal Čihař
8023340a25 Include common libraries in setup
We use PMA_fatalError which in turn needs Response and related objects.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-26 14:25:57 +01:00
Michal Čihař
fe62b69a5b Use hash_equals for comparing token
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-26 13:00:50 +01:00
Madhura Jayaratne
27eb98faed Escape javascript variable content
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2016-01-26 22:21:24 +11:00
Michal Čihař
6fe54dfa00 Use phpseclib's Crypt::Random to generate CSRF token
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-26 09:51:12 +01:00
Michal Čihař
2369daa7f5 Use full alphabet to generate random passwords
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-26 09:39:19 +01:00
Michal Čihař
6a96e67487 Use secure RNG if available
Recent browsers come with better RNG, so let's use it for generating
password instead of Math.random if available.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-26 09:39:09 +01:00
Madhura Jayaratne
0ce4fd2750 Fix XSS in DB_search.php
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2016-01-19 21:01:32 +11:00
Madhura Jayaratne
9f3488fc3a Fix XSS in zoom search
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2016-01-19 20:59:37 +11:00
Madhura Jayaratne
ac81596bfc [Security] Fix path disclosure, items 1.4.x, 1.5 and 1.6
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2016-01-15 08:12:48 +11:00
Marc Delisle
66149607b1 4.0.10.12 release
Signed-off-by: Marc Delisle <marc@infomarc.info>
2015-12-25 15:25:34 -05:00
Marc Delisle
f79d30dd98 [Security] Path disclosure, see PMASA-2015-6
Signed-off-by: Marc Delisle <marc@infomarc.info>
2015-12-25 15:24:18 -05:00
Marc Delisle
2694c36ef6 4.0.10.11 release
Signed-off-by: Marc Delisle <marc@infomarc.info>
2015-09-23 07:00:32 -04:00
Madhura Jayaratne
9730b16dd0 issue #11464 phpMyAdmin suggests upgrading to newer version not usable on that system
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2015-09-22 23:59:20 +10:00
Marc Delisle
d81165f345 4.0.10.10 release
Signed-off-by: Marc Delisle <marc@infomarc.info>
2015-05-13 11:06:36 -04:00
Madhura Jayaratne
e97e7fb0ea bug #4900 [security] Vulnerability allowing Man-in-the-middle attack
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2015-05-13 07:32:02 +05:30
Madhura Jayaratne
fea1d39fef bug #4899 [security] CSRF vulnerability in setup
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2015-05-12 19:56:53 +05:30
Marc Delisle
a395665715 4.0.10.9 release
Signed-off-by: Marc Delisle <marc@infomarc.info>
2015-03-04 10:34:18 -05:00
Marc Delisle
e1a68ad02c bug [security] Risk of BREACH attack
Signed-off-by: Marc Delisle <marc@infomarc.info>
2015-03-04 10:32:07 -05:00
Marc Delisle
5004dc4098 4.0.10.8 release
Signed-off-by: Marc Delisle <marc@infomarc.info>
2015-01-07 08:10:02 -05:00
Marc Delisle
1da7417fc2 ChangeLog entries
Signed-off-by: Marc Delisle <marc@infomarc.info>
2015-01-07 08:06:31 -05:00
Ian P. Christian
394bf9183c Support early versions of PHP5.2 (register_shutdown_function)
Signed-off-by: Ian P. Christian <ichristian@users.sf.net>
2015-01-07 08:03:09 -05:00
Ian P. Christian
9b7fbe29ce Recursive function too deep
Signed-off-by: Ian P. Christian <ichristian@users.sf.net>
2015-01-07 07:52:29 -05:00
Michal Čihař
26ce63dbde Cache composer cache
Signed-off-by: Michal Čihař <michal@cihar.com>
2014-12-04 13:14:56 +01:00
Michal Čihař
853f7255c5 Create database for test
Signed-off-by: Michal Čihař <michal@cihar.com>
2014-12-04 13:12:21 +01:00
Michal Čihař
9daeaff5f0 Use composer to install correct phpunit version
Signed-off-by: Michal Čihař <michal@cihar.com>
2014-12-04 13:09:26 +01:00
Marc Delisle
00828f9ccb 4.0.10.7 release
Signed-off-by: Marc Delisle <marc@infomarc.info>
2014-12-03 07:55:56 -05:00
Madhura Jayaratne
095729d812 bug #4611 [security] DOS attack with long passwords
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2014-12-01 20:49:45 +05:30
Marc Delisle
13a288d0da 4.0.10.6 release
Signed-off-by: Marc Delisle <marc@infomarc.info>
2014-11-20 10:09:42 -05:00
Madhura Jayaratne
c7685e5acd bug #4597 [security] XSS through pma_fontsize cookie
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2014-11-18 10:15:34 +05:30
Madhura Jayaratne
c5783321cd bug #4598 [security] XSS in multi submit
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2014-11-17 12:13:09 +05:30
Madhura Jayaratne
2e3f0b9457 bug #4594 [security] Path traversal in file inclusion of GIS factory
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2014-11-17 11:03:55 +05:30
Madhura Jayaratne
58cdd91fc8 bug #4579 [security] XSS vulnerability in zoom search page
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2014-11-04 16:20:15 +05:30
Madhura Jayaratne
42b64e12b5 bug #4578 XSS vulnerability in table print view
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2014-11-04 16:05:06 +05:30
Marc Delisle
d0f7dc7990 4.0.10.5 release
Signed-off-by: Marc Delisle <marc@infomarc.info>
2014-10-21 10:07:51 -04:00
Madhura Jayaratne
a150ea1df4 bug #4563 [security] XSS in monitor query analyzer
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2014-10-18 06:52:40 +05:30
Madhura Jayaratne
57594febab bug #4562 [security] XSS in debug SQL output
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2014-10-17 18:07:08 +05:30
Marc Delisle
5118938f10 4.0.10.4 release
Signed-off-by: Marc Delisle <marc@infomarc.info>
2014-10-01 07:20:09 -04:00
Marc Delisle
c6c77589a5 [security] XSS with malicious ENUM values
Signed-off-by: Marc Delisle <marc@infomarc.info>
2014-09-28 09:48:13 -04:00
Marc Delisle
ceb7d7e1b2 4.0.10.3 release
Signed-off-by: Marc Delisle <marc@infomarc.info>
2014-09-13 11:12:44 -04:00
Marc Delisle
ab0dba4533 bug #4530 [security] DOM based XSS that results to a CSRF that creates a ROOT account in certain conditions
Signed-off-by: Marc Delisle <marc@infomarc.info>
2014-09-12 08:22:14 -04:00
Marc Delisle
5e52612841 4.0.10.2 release
Signed-off-by: Marc Delisle <marc@infomarc.info>
2014-08-17 06:59:44 -04:00
Madhura Jayaratne
098caf93b6 bug #4517 [security] XSS in relation view
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2014-08-16 22:00:13 +05:30
Madhura Jayaratne
5cd9839467 Fix typo
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2014-08-06 20:00:45 +05:30
Madhura Jayaratne
03b92aa6e9 bug #4504 [security] Self-XSS in query charts
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2014-08-06 19:58:02 +05:30
Madhura Jayaratne
3668255202 bug #4503 [security] Self-XSSes in monitor
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2014-08-06 07:28:14 +05:30
Madhura Jayaratne
0433d463b6 bug #4502 [security] Self-XSS in enum value editor
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2014-08-06 07:20:52 +05:30
Madhura Jayaratne
285ed5b8d3 bug #4501 [security] XSS in table browse page 2014-08-06 07:16:17 +05:30
Marc Delisle
f86761326c 4.0.10.1 release
Signed-off-by: Marc Delisle <marc@infomarc.info>
2014-07-17 17:35:22 -04:00
Marc Delisle
a92753bd65 bug #4492 [security] XSS in AJAX confirmation messages
Signed-off-by: Marc Delisle <marc@infomarc.info>
2014-07-17 17:06:00 -04:00
Madhura Jayaratne
1b55924356 bug #4488 [security] XSS injection due to unescaped table name (triggers)
Signed-off-by: Marc Delisle <marc@infomarc.info>
2014-07-17 16:29:40 -04:00
Marc Delisle
82161a6c30 4.0.10 release
Signed-off-by: Marc Delisle <marc@infomarc.info>
2013-12-04 12:36:40 -05:00
236 changed files with 2565 additions and 2575 deletions

View File

@ -2,5 +2,16 @@ language: php
php:
- "5.4"
- "5.3"
before_script: ./scripts/generate-mo --quiet
script: phpunit --configuration phpunit.xml.nocoverage
- "5.2"
sudo: false
before_script:
- export PATH=~/.composer/vendor/bin/:$PATH
- mysql -uroot -e "CREATE DATABASE test;"
- if [ $TRAVIS_PHP_VERSION != "5.2" ] ; then composer install --dev --no-interaction ; fi
- ./scripts/generate-mo --quiet
script:
- if [ $TRAVIS_PHP_VERSION != "5.2" ] ; then ./vendor/bin/phpunit --configuration phpunit.xml.nocoverage ; else phpunit --configuration phpunit.xml.nocoverage ; fi
- git ls-files | grep '\.php$' | xargs -n1 php -l
cache:
directories:
- $HOME/.composer/cache/

137
ChangeLog
View File

@ -1,7 +1,140 @@
phpMyAdmin - ChangeLog
======================
4.0.10.0 (not yet released)
4.0.10.20 (2017-03-28)
- issue #12881 Fix database search when locale is not 'en'
- issue [security] Possible to bypass $cfg['Servers'][$i]['AllowNoPassword'], see PMASA-2017-08
4.0.10.19 (2017-01-23)
- issue [security] Multiple vulnerabilities in setup script, see PMASA-2016-44.
- issue [security] Open redirect, see PMASA-2017-1.
- issue [security] php-gettext code execution, see PMASA-2017-2.
- issue [security] DOS vulnerabiltiy in table editing, see PMASA-2017-3.
- issue [security] CSS injection in themes, see PMASA-2017-4.
- issue [security] SSRF in replication, see PMASA-2017-6.
- issue [security] DOS in replication status, see PMASA-2017-7.
4.0.10.18 (2016-11-24)
- issue #12485 Do not show warning about short blowfish_secret if none is set
- issue [security] Open redirection issue, see PMASA-2016-57
- issue [security] Unsafe generation of $cfg['blowfish_secret'], see PMASA-2016-58
- issue [security] phpMyAdmin's phpinfo functionality is removed, see PMASA-2016-59
- issue [security] AllowRoot and allow/deny rule bypass with specially-crafted username, see PMASA-2016-60
- issue [security] Username matching weaknesses with allow/deny rules, see PMASA-2016-61
- issue [security] Full path disclosure (FPD) weaknesses, see PMASA-2016-63
- issue [security] Multiple cross-site scripting (XSS) weaknesses, see PMASA-2016-64
- issue [security] Multiple denial-of-service (DOS) vulnerabilities, see PMASA-2016-65
- issue [security] Possible to bypass white-list protection for URL redirection, see PMASA-2016-66
- issue [security] Multiple SQL injection vulnerabilities, see PMASA-2016-69
- issue [security] Incorrect serialized string parsing, see PMASA-2016-70
- issue [security] CSRF token not stripped from the URL, see PMASA-2016-71
4.0.10.17 (2016-08-16)
- issue [security] Weaknesses with cookie encryption, see PMASA-2016-29
- issue [security] Improve session cookie code for openid.php and signon.php example files
- issue [security] Full path disclosure in openid.php and signon.php example files
- issue [security] Multiple XSS vulnerabilities, see PMASA-2016-30
- issue [security] Unsafe generation of BlowfishSecret (when not supplied by the user)
- issue [security] Referrer leak when phpinfo is enabled
- issue [security] PHP code injection, see PMASA-2016-32
- issue [security] Full path disclosure, see PMASA-2016-33
- issue [security] SQL injection attack, see PMASA-2016-34
- issue [security] Local file exposure through LOAD DATA LOCAL INFILE, see PMASA-2016-35
- issue [security] Local file exposure through symlinks with UploadDir, see PMASA-2016-36
- issue [security] Path traversal with SaveDir and UploadDir, see PMASA-2016-37
- issue [security] Denial-of-service attack through transformation feature, see PMASA-2016-41
- issue [security] SQL injection vulnerability as control user, see PMASA-2016-42
- issue [security] Verify data before unserializing, see PMASA-2016-43
- issue [security] Use HTTPS for wiki links
- issue Remove Swekey support
- issue [security] Denial-of-service attack with $cfg['AllowArbitraryServer'] = true and persistent connections, see PMASA-2016-45
- issue [security] Improve SSL certificate handling
- issue [security] Fix full path disclosure in debugging code
- issue [security] Possible circumvention of IP-based allow/deny rules with IPv6 and proxy server, see PMASA-2016-47
- issue [security] Detect if user is logged in, see PMASA-2016-48
- issue [security] Bypass URL redirection protection, see PMASA-2016-49
- issue [security] Referrer leak, see PMASA-2016-50
- issue [security] Reflected File Download, see PMASA-2016-51
- issue [security] ArbitraryServerRegexp bypass, see PMASA-2016-52
- issue [security] Denial-of-service attack by entering long password, see PMASA-2016-53
- issue [security] Remote code execution vulnerability when running as CGI, see PMASA-2016-54
- issue [security] Denial-of-service attack when PHP uses dbase extension, see PMASA-2016-55
- issue [security] Remove tode execution vulnerability when PHP uses dbase extension, see PMASA-2016-56
- issue [security] Denial-of-service attack by using for loops, see PMASA-2016-46
4.0.10.16 (2016-06-23)
- issue [security] User SQL queries can be revealed through URL GET parameters, see PMASA-2016-14
- issue [security] Limit list of sites which can be passwd through url.php.
- issue [security] BBCode injection in setup script, see PMASA-2016-17
- issue [security] DOS attack vulnerability, see PMASA-2016-22
- issue [security] Multiple full path disclosure vulnerabilities, see PMASA-2016-26
- issue [security] XSS attack when checking database privileges, see PMASA-2016-21
- issue [security] XSS attack when MySQL server is using a specific payload log_bin directive, see PMASA-2016-26
- issue [security] XSS vulnerabilities in Transformation feature, PMASA-2016-28
4.0.10.15 (2016-02-29)
- issue [security] Multiple XSS vulnerabilities, see PMASA-2016-11.
4.0.10.14 (2016-01-29)
- issue #11891 Error with PMA 4.0.10.13 with PHP 5.2
4.0.10.13 (2016-01-28)
- issue [Security] Multiple full path disclosure vulnerabilities, see PMASA-2016-1
- issue [Security] Unsafe generation of CSRF token, see PMASA-2016-2
- issue [Security] Multiple XSS vulnerabilities, see PMASA-2016-3
- issue [Security] Insecure password generation in JavaScript, see PMASA-2016-4
- issue [Security] Unsafe comparison of CSRF token, see PMASA-2016-5
4.0.10.12 (2015-12-25)
- issue [Security] Path disclosure, see PMASA-2015-6
4.0.10.11 (2015-09-23)
- issue #11464 phpMyAdmin suggests upgrading to newer version not usable on that system
4.0.10.10 (2015-05-13)
- bug #4899 [security] CSRF vulnerability in setup
- bug #4900 [security] Vulnerability allowing Man-in-the-middle attack
4.0.10.9 (2015-03-04)
- bug [security] Risk of BREACH attack, see PMASA-2015-1
4.0.10.8 (2015-01-07)
- rfe #1588 recursive function too deep - operator change suggestion
- rfe #1589 support early versions of PHP5.2 (register_shutdown_function)
4.0.10.7 (2014-12-03)
- bug #4611 [security] DOS attack with long passwords
4.0.10.6 (2014-11-20)
- bug #4578 [security] XSS vulnerability in table print view
- bug #4579 [security] XSS vulnerability in zoom search page
- bug #4594 [security] Path traversal in file inclusion of GIS factory
- bug #4598 [security] XSS in multi submit
- bug #4597 [security] XSS through pma_fontsize cookie
4.0.10.5 (2014-10-21)
- bug #4562 [security] XSS in debug SQL output
- bug #4563 [security] XSS in monitor query analyzer
4.0.10.4 (2014-10-01)
- bug #4544 [security] XSS vulnerabilities in table search and table structure pages
4.0.10.3 (2014-09-13)
- bug #4530 [security] DOM based XSS that results to a CSRF that creates a
ROOT account in certain conditions
4.0.10.2 (2014-08-17)
- bug #4501 [security] XSS in table browse page
- bug #4502 [security] Self-XSS in enum value editor
- bug #4503 [security] Self-XSSes in monitor
- bug #4504 [security] Self-XSS in query charts
- bug #4517 [security] XSS in relation view
4.0.10.1 (2014-07-17)
- bug #4488 [security] XSS injection due to unescaped table name (triggers)
- bug #4492 [security] XSS in AJAX confirmation messages
4.0.10.0 (2013-12-04)
- bug #4150 Clicking database name in query window opens a new tab
- bug #4141 Wrong page is shown after editing; also, do not show a modal
dialog for multi-row edit
@ -330,7 +463,7 @@ underscore
- bug #3776 [cookies] Login without auth on second server
--- Older ChangeLogs can be found on our project website ---
http://www.phpmyadmin.net/old-stuff/ChangeLogs/
https://www.phpmyadmin.net/old-stuff/ChangeLogs/
# vim: et ts=4 sw=4 sts=4
# vim: ft=changelog fenc=utf-8

10
README
View File

@ -1,11 +1,11 @@
phpMyAdmin - Readme
===================
Version 4.0.10-dev
Version 4.0.10.20
A set of PHP-scripts to manage MySQL over the web.
http://www.phpmyadmin.net/
https://www.phpmyadmin.net/
Copyright
---------
@ -13,7 +13,7 @@ Copyright
Copyright (C) 1998-2000
Tobias Ratschiller <tobias_at_ratschiller.com>
Copyright (C) 2001-2013
Copyright (C) 2001-2014
Marc Delisle <marc_at_infomarc.info>
Olivier Müller <om_at_omnis.ch>
Robin Johnson <robbat2_at_users.sourceforge.net>
@ -55,7 +55,7 @@ For a summary of features, please see the documentation in the doc folder.
Download
--------
You can get the newest version at http://www.phpmyadmin.net/.
You can get the newest version at https://www.phpmyadmin.net/.
More Information
----------------
@ -65,7 +65,7 @@ Please see the documentation in the doc folder.
Support
-------
See reference about support forums under http://www.phpmyadmin.net/
See reference about support forums under https://www.phpmyadmin.net/
Enjoy!

View File

@ -3,7 +3,7 @@ phpMyAdmin
A set of PHP-scripts to manage MySQL over the web.
http://www.phpmyadmin.net/
https://www.phpmyadmin.net/
Status
------
@ -23,14 +23,14 @@ Translations:
Download
--------
You can get the newest version at http://www.phpmyadmin.net/.
You can get the newest version at https://www.phpmyadmin.net/.
More Information
----------------
Please see the documentation in the doc folder or at http://docs.phpmyadmin.net/.
Please see the documentation in the doc folder or at https://docs.phpmyadmin.net/.
Support
-------
See reference about support forums under http://www.phpmyadmin.net/
See reference about support forums under https://www.phpmyadmin.net/

View File

@ -52,15 +52,15 @@ $github_url = 'https://github.com/phpmyadmin/phpmyadmin/';
$replaces = array(
'@(http://[./a-zA-Z0-9.-_-]*[/a-zA-Z0-9_])@'
=> '<a href="\\1">\\1</a>',
=> '<a href="./url.php?url=\\1">\\1</a>',
// sourceforge users
'/([0-9]{4}-[0-9]{2}-[0-9]{2}) (.+[^ ]) +&lt;(.*)@users.sourceforge.net&gt;/i'
=> '\\1 <a href="https://sourceforge.net/users/\\3/">\\2</a>',
=> '\\1 <a href="./url.php?url=https://sourceforge.net/users/\\3/">\\2</a>',
'/thanks to ([^\(\r\n]+) \(([-\w]+)\)/i'
=> 'thanks to <a href="https://sourceforge.net/users/\\2/">\\1</a>',
=> 'thanks to <a href="./url.php?url=https://sourceforge.net/users/\\2/">\\1</a>',
'/thanks to ([^\(\r\n]+) -\s+([-\w]+)/i'
=> 'thanks to <a href="https://sourceforge.net/users/\\2/">\\1</a>',
=> 'thanks to <a href="./url.php?url=https://sourceforge.net/users/\\2/">\\1</a>',
// mail address
'/([0-9]{4}-[0-9]{2}-[0-9]{2}) (.+[^ ]) +&lt;(.*@.*)&gt;/i'
@ -68,55 +68,55 @@ $replaces = array(
// linking patches
'/patch\s*#?([0-9]{6,})/i'
=> '<a href="' . $tracker_url . '">patch #\\1</a>',
=> '<a href="./url.php?url=' . $tracker_url . '">patch #\\1</a>',
// linking RFE
'/(?:rfe|feature)\s*#?([0-9]{6,})/i'
=> '<a href="https://sourceforge.net/support/tracker.php?aid=\\1">RFE #\\1</a>',
=> '<a href="./url.php?url=https://sourceforge.net/support/tracker.php?aid=\\1">RFE #\\1</a>',
// linking files
'/(\s+)([\\/a-z_0-9\.]+\.(?:php3?|html|pl|js|sh))/i'
=> '\\1<a href="' . $github_url . 'commits/HEAD/\\2">\\2</a>',
=> '\\1<a href="./url.php?url=' . $github_url . 'commits/HEAD/\\2">\\2</a>',
// FAQ entries
'/FAQ ([0-9]+)\.([0-9a-z]+)/i'
=> '<a href="http://docs.phpmyadmin.net/en/latest/faq.html#faq\\1-\\2">FAQ \\1.\\2</a>',
=> '<a href="./url.php?url=https://docs.phpmyadmin.net/en/latest/faq.html#faq\\1-\\2">FAQ \\1.\\2</a>',
// linking bugs
'/bug\s*#?([0-9]{6,})/i'
=> '<a href="https://sourceforge.net/support/tracker.php?aid=\\1">bug #\\1</a>',
=> '<a href="./url.php?url=https://sourceforge.net/support/tracker.php?aid=\\1">bug #\\1</a>',
// all other 6+ digit numbers are treated as bugs
'/(?<!bug|RFE|patch) #?([0-9]{6,})/i'
=> '<a href="' . $tracker_url . '">bug #\\1</a>',
=> '<a href="./url.php?url=' . $tracker_url . '">bug #\\1</a>',
// transitioned SF.net project bug/rfe/patch links
// by the time we reach 6-digit numbers, we can probably retire the above links
'/patch\s*#?([0-9]{4,5}) /i'
=> '<a href="' . $tracker_url_patch . '">patch #\\1</a> ',
=> '<a href="./url.php?url=' . $tracker_url_patch . '">patch #\\1</a> ',
'/(?:rfe|feature)\s*#?([0-9]{4,5}) /i'
=> '<a href="' . $tracker_url_rfe . '">RFE #\\1</a> ',
=> '<a href="./url.php?url=' . $tracker_url_rfe . '">RFE #\\1</a> ',
'/bug\s*#?([0-9]{4,5}) /i'
=> '<a href="' . $tracker_url_bug . '">bug #\\1</a> ',
=> '<a href="./url.php?url=' . $tracker_url_bug . '">bug #\\1</a> ',
'/(?<!bug|RFE|patch) #?([0-9]{4,5}) /i'
=> '<a href="' . $tracker_url_bug . '">bug #\\1</a> ',
=> '<a href="./url.php?url=' . $tracker_url_bug . '">bug #\\1</a> ',
// CVE/CAN entries
'/((CAN|CVE)-[0-9]+-[0-9]+)/'
=> '<a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=\\1">\\1</a>',
=> '<a href="./url.php?url=http://cve.mitre.org/cgi-bin/cvename.cgi?name=\\1">\\1</a>',
// PMASAentries
'/(PMASA-[0-9]+-[0-9]+)/'
=> '<a href="http://www.phpmyadmin.net/home_page/security/\\1.php">\\1</a>',
=> '<a href="./url.php?url=https://www.phpmyadmin.net/security/\\1/">\\1</a>',
// Highlight releases (with links)
'/([0-9]+)\.([0-9]+)\.([0-9]+)\.0 (\([0-9-]+\))/'
=> '<a name="\\1_\\2_\\3"></a>'
. '<a href="' . $github_url . 'commits/RELEASE_\\1_\\2_\\3">'
. '<a href="./url.php?url=' . $github_url . 'commits/RELEASE_\\1_\\2_\\3">'
. '\\1.\\2.\\3.0 \\4</a>',
'/([0-9]+)\.([0-9]+)\.([0-9]+)\.([1-9][0-9]*) (\([0-9-]+\))/'
=> '<a name="\\1_\\2_\\3_\\4"></a>'
. '<a href="' . $github_url . 'commits/RELEASE_\\1_\\2_\\3_\\4">'
. '<a href="./url.php?url=' . $github_url . 'commits/RELEASE_\\1_\\2_\\3_\\4">'
. '\\1.\\2.\\3.\\4 \\5</a>',
// Highlight releases (not linkable)
@ -146,6 +146,7 @@ echo '</pre>';
var links = document.getElementsByTagName("a");
for(var i = 0; i < links.length; i++) {
links[i].target = "_blank";
links[i].rel = "noopener noreferrer";
}
</script>
</body>

View File

@ -3,22 +3,27 @@
"type": "application",
"description": "MySQL web administration tool",
"keywords": ["phpmyadmin","mysql","web"],
"homepage": "http://www.phpmyadmin.net/",
"homepage": "https://www.phpmyadmin.net/",
"license": "GPL-2.0+",
"authors": [
{
"name": "The phpMyAdmin Team",
"email": "phpmyadmin-devel@lists.sourceforge.net",
"homepage": "http://www.phpmyadmin.net/home_page/team.php"
"homepage": "https://www.phpmyadmin.net/team/"
}
],
"support": {
"forum": "https://sourceforge.net/p/phpmyadmin/discussion/Help",
"issues": "https://sourceforge.net/p/phpmyadmin/bugs/",
"wiki": "http://wiki.phpmyadmin.net/",
"wiki": "https://wiki.phpmyadmin.net/",
"source": "https://github.com/phpmyadmin/phpmyadmin"
},
"require": {
"php": ">=5.2.0"
},
"require-dev": {
"satooshi/php-coveralls": ">=0.6",
"phpunit/phpunit": "<4.2",
"phpunit/phpunit-selenium": ">=1.2"
}
}

View File

@ -5,14 +5,14 @@
* manual configuration. For easier setup you can use setup/
*
* All directives are explained in documentation in the doc/ folder
* or at <http://docs.phpmyadmin.net/>.
* or at <https://docs.phpmyadmin.net/>.
*
* @package PhpMyAdmin
*/
/*
* This is needed for cookie based authentication to encrypt password in
* cookie
* cookie. Needs to be 32 chars long.
*/
$cfg['blowfish_secret'] = 'a8b7c6d'; /* YOU MUST FILL IN THIS FOR COOKIE AUTH! */
@ -58,8 +58,6 @@ $cfg['Servers'][$i]['AllowNoPassword'] = false;
// $cfg['Servers'][$i]['designer_coords'] = 'pma__designer_coords';
// $cfg['Servers'][$i]['userconfig'] = 'pma__userconfig';
// $cfg['Servers'][$i]['recent'] = 'pma__recent';
/* Contrib / Swekey authentication */
// $cfg['Servers'][$i]['auth_swekey_config'] = '/etc/swekey-pma.conf';
/*
* End of servers configuration
@ -136,6 +134,6 @@ $cfg['SaveDir'] = '';
/*
* You can find more configuration options in the documentation
* in the doc/ folder or at <http://docs.phpmyadmin.net/>.
* in the doc/ folder or at <https://docs.phpmyadmin.net/>.
*/
?>

View File

@ -49,7 +49,7 @@ copyright = u'2012 - 2013, The phpMyAdmin devel team'
# built documents.
#
# The short X.Y version.
version = '4.0.10-dev'
version = '4.0.10.20'
# The full version, including alpha/beta/rc tags.
release = version

View File

@ -321,15 +321,6 @@ Server connection settings
"phpMyAdmin " and either :config:option:`$cfg['Servers'][$i]['verbose']` or
:config:option:`$cfg['Servers'][$i]['host']` will be used.
.. _servers_auth_swekey_config:
.. config:option:: $cfg['Servers'][$i]['auth_swekey_config']
:type: string
:default: ``''``
The name of the file containing :ref:`swekey` ids and login names for hardware
authentication. Leave empty to deactivate this feature.
.. _servers_user:
.. config:option:: $cfg['Servers'][$i]['user']
@ -1195,11 +1186,18 @@ Cookie authentication options
:type: string
:default: ``''``
The "cookie" auth\_type uses blowfish algorithm to encrypt the
password. If you are using the "cookie" auth\_type, enter here a
random passphrase of your choice. It will be used internally by the
blowfish algorithm: you wont be prompted for this passphrase. There
is no maximum length for this secret.
The "cookie" auth\_type uses AES algorithm to encrypt the password. If you
are using the "cookie" auth\_type, enter here a random passphrase of your
choice. It will be used internally by the AES algorithm: you wont be
prompted for this passphrase.
The secret should be 32 characters long. Using shorter will lead to weaker security
of encrypted cookies, using longer will cause no harm.
.. note::
The configuration is called blowfish_secret for historical reasons as
Blowfish algorithm was originally used to do the encryption.
.. versionchanged:: 3.1.0
Since version 3.1.0 phpMyAdmin can generate this on the fly, but it
@ -1412,11 +1410,6 @@ Main panel
You can additionally hide more information by using
:config:option:`$cfg['Servers'][$i]['verbose']`.
.. config:option:: $cfg['ShowPhpInfo']
:type: boolean
:default: false
.. config:option:: $cfg['ShowChgPassword']
:type: boolean
@ -1427,18 +1420,11 @@ Main panel
:type: boolean
:default: true
Defines whether to display the :guilabel:`PHP information` and
Defines whether to display the
:guilabel:`Change password` links and form for creating database or not at
the starting main (right) frame. This setting does not check MySQL commands
entered directly.
Please note that to block the usage of ``phpinfo()`` in scripts, you have to
put this in your :file:`php.ini`:
.. code-block:: ini
disable_functions = phpinfo()
Also note that enabling the :guilabel:`Change password` link has no effect
with config authentication mode: because of the hard coded password value
in the configuration file, end users can't be allowed to change their

View File

@ -9,4 +9,4 @@ to make phpMyAdmin a useful tool.
You can check out all the possibilities to contribute in the
`contribute section on our website
<http://www.phpmyadmin.net/home_page/improve.php>`_.
<https://www.phpmyadmin.net/contribute/>`_.

View File

@ -4,7 +4,7 @@ FAQ - Frequently Asked Questions
================================
Please have a look at our `Link section
<http://www.phpmyadmin.net/home_page/docs.php>`_ on the official
<https://www.phpmyadmin.net/home_page/docs.php>`_ on the official
phpMyAdmin homepage for in-depth coverage of phpMyAdmin's features and
or interface.
@ -904,7 +904,7 @@ just put your own input-elements inside. If you use a custom submit
input field, the form will submit itself to the displaying page again,
where you can validate the $HTTP\_POST\_VARS in a transformation. For
a tutorial on how to effectively use transformations, see our `Link
section <http://www.phpmyadmin.net/home_page/docs.php>`_ on the
section <https://www.phpmyadmin.net/home_page/docs.php>`_ on the
official phpMyAdmin-homepage.
.. _faq3_9:
@ -1931,7 +1931,7 @@ Translations are very welcome and all you need to have are the
language skills. The easiest way is to use our `online translation
service <https://l10n.cihar.com/projects/phpmyadmin/>`_. You can check
out all the possibilities to translate in the `translate section on
our website <http://www.phpmyadmin.net/home_page/translate.php>`_.
our website <https://www.phpmyadmin.net/home_page/translate.php>`_.
.. _faq7_3:
@ -1941,7 +1941,7 @@ our website <http://www.phpmyadmin.net/home_page/translate.php>`_.
We welcome every contribution to the development of phpMyAdmin. You
can check out all the possibilities to contribute in the `contribute
section on our website
<http://www.phpmyadmin.net/home_page/improve.php>`_.
<https://www.phpmyadmin.net/home_page/improve.php>`_.
.. seealso:: :ref:`developers`
@ -1955,7 +1955,7 @@ Security
8.1 Where can I get information about the security alerts issued for phpMyAdmin?
--------------------------------------------------------------------------------
Please refer to <http://www.phpmyadmin.net/home_page/security.php>.
Please refer to <https://www.phpmyadmin.net/home_page/security.php>.
.. _faq8_2:

View File

@ -45,7 +45,7 @@ Currently phpMyAdmin can:
* create, edit, call, export and drop stored procedures and functions
* create, edit, export and drop events and triggers
* communicate in `62 different languages
<http://www.phpmyadmin.net/home_page/translations.php>`_
<https://www.phpmyadmin.net/home_page/translations.php>`_
A word about users

View File

@ -8,11 +8,11 @@ The definitive guide to using phpMyAdmin is the book Mastering phpMyAdmin for
Effective MySQL Management by Marc Delisle. You can get information on that
book and other officially endorsed `books at the phpMyAdmin site`_.
.. _books at the phpMyAdmin site: http://www.phpmyadmin.net/home_page/docs.php?books
.. _books at the phpMyAdmin site: https://www.phpmyadmin.net/home_page/docs.php?books
Tutorials
---------
Third party tutorials and articles are listed on our `wiki page`_.
.. _wiki page: http://wiki.phpmyadmin.net/pma/Articles
.. _wiki page: https://wiki.phpmyadmin.net/pma/Articles

View File

@ -60,7 +60,8 @@ simple configuration may look like this:
<?php
$cfg['blowfish_secret'] = 'ba17c1ec07d65003'; // use here a value of your choice
// use here a value of your choice at least 32 chars long
$cfg['blowfish_secret'] = '1{dd0`<Q),5XP_:R9UK%%8\"EEcyH#{o';
$i=0;
$i++;
@ -91,51 +92,14 @@ For a full explanation of possible configuration values, see the
Using Setup script
------------------
Instead of manually editing :file:`config.inc.php`, you can use the `Setup
Script <setup/>`_. First you must manually create a folder ``config``
in the phpMyAdmin directory. This is a security measure. On a
Linux/Unix system you can use the following commands:
Instead of manually editing :file:`config.inc.php`, you can use phpMyAdmin's
setup feature. The file can be generated using the setup and you can download it
for upload to the server.
.. code-block:: sh
cd phpMyAdmin
mkdir config # create directory for saving
chmod o+rw config # give it world writable permissions
And to edit an existing configuration, copy it over first:
.. code-block:: sh
cp config.inc.php config/ # copy current configuration for editing
chmod o+w config/config.inc.php # give it world writable permissions
On other platforms, simply create the folder and ensure that your web
server has read and write access to it. :ref:`faq1_26` can help with
this.
Next, open ``setup/`` in your browser. If you have an existing configuration,
use the ``Load`` button to bring its content inside the setup panel.
Note that **changes are not saved to disk until explicitly choose ``Save``**
from the *Configuration* area of the screen. Normally the script saves the new
:file:`config.inc.php` to the ``config/`` directory, but if the webserver does
not have the proper permissions you may see the error "Cannot load or
save configuration." Ensure that the ``config/`` directory exists and
has the proper permissions - or use the ``Download`` link to save the
config file locally and upload it (via FTP or some similar means) to the
proper location.
Once the file has been saved, it must be moved out of the ``config/``
directory and the permissions must be reset, again as a security
measure:
.. code-block:: sh
mv config/config.inc.php . # move file to current directory
chmod o-rw config.inc.php # remove world read and write permissions
rm -rf config # remove not needed directory
Next, open your browser and visit the location where you installed phpMyAdmin,
with the ``/setup`` suffix. The changes are not saved to the server, you need to
use the :guilabel:`Download` button to save them to your computer and then upload
to the server.
Now the file is ready to be used. You can choose to review or edit the
file with your favorite editor, if you prefer to set some advanced
@ -377,35 +341,6 @@ Config authentication mode
of which are beyond the scope of this manual but easily searchable
with Google).
.. index:: pair: Swekey; Authentication mode
.. _swekey:
Swekey authentication mode
--------------------------
The Swekey is a low cost authentication USB key that can be used in
web applications. When Swekey authentication is activated, phpMyAdmin
requires the users's Swekey to be plugged before entering the login
page (currently supported for cookie authentication mode only). Swekey
Authentication is disabled by default. To enable it, add the following
line to :file:`config.inc.php`:
.. code-block:: php
$cfg['Servers'][$i]['auth_swekey_config'] = '/etc/swekey.conf';
You then have to create the ``swekey.conf`` file that will associate
each user with their Swekey Id. It is important to place this file
outside of your web server's document root (in the example, it is
located in ``/etc``). A self documented sample file is provided in the
``examples`` directory. Feel free to use it with your own users'
information. If you want to purchase a Swekey please visit
`http://phpmyadmin.net/auth\_key <http://phpmyadmin.net/auth_key>`_
since this link provides funding for phpMyAdmin.
.. seealso:: :config:option:`$cfg['Servers'][$i]['auth_swekey_config']`
Securing your phpMyAdmin installation
+++++++++++++++++++++++++++++++++++++

View File

@ -29,7 +29,7 @@ options, you can consult your *<www.your-host.com>/<your-install-
dir>/transformation\_overview.php* installation.
For a tutorial on how to effectively use transformations, see our
`Link section <http://www.phpmyadmin.net/home_page/docs.php>`_ on the
`Link section <https://www.phpmyadmin.net/home_page/docs.php>`_ on the
official phpMyAdmin homepage.
.. _transformationshowto:

View File

@ -61,12 +61,22 @@ echo $contents;
<?php
}
function die_error($e)
{
$contents = "<div class='relyingparty_results'>\n";
$contents .= "<pre>" . htmlspecialchars($e->getMessage()) . "</pre>\n";
$contents .= "</div class='relyingparty_results'>";
show_page($contents);
exit;
}
/* Need to have cookie visible from parent directory */
session_set_cookie_params(0, '/', '', 0);
session_set_cookie_params(0, '/', '', true, true);
/* Create signon session */
$session_name = 'SignonSession';
session_name($session_name);
session_start();
@session_start();
// Determine realm and return_to
$base = 'http';
@ -96,9 +106,9 @@ OpenID: <input type="text" name="identifier" /><br />
}
/* Grab identifier */
if (isset($_POST['identifier'])) {
if (isset($_POST['identifier']) && is_string($_POST['identifier'])) {
$identifier = $_POST['identifier'];
} else if (isset($_SESSION['identifier'])) {
} else if (isset($_SESSION['identifier']) && is_string($_SESSION['identifier'])) {
$identifier = $_SESSION['identifier'];
} else {
$identifier = null;
@ -107,24 +117,16 @@ if (isset($_POST['identifier'])) {
/* Create OpenID object */
try {
$o = new OpenID_RelyingParty($returnTo, $realm, $identifier);
} catch (OpenID_Exception $e) {
$contents = "<div class='relyingparty_results'>\n";
$contents .= "<pre>" . $e->getMessage() . "</pre>\n";
$contents .= "</div class='relyingparty_results'>";
show_page($contents);
exit;
} catch (Exception $e) {
die_error($e);
}
/* Redirect to OpenID provider */
if (isset($_POST['start'])) {
try {
$authRequest = $o->prepare();
} catch (OpenID_Exception $e) {
$contents = "<div class='relyingparty_results'>\n";
$contents .= "<pre>" . $e->getMessage() . "</pre>\n";
$contents .= "</div class='relyingparty_results'>";
show_page($contents);
exit;
} catch (Exception $e) {
die_error($e);
}
$url = $authRequest->getAuthorizeURL();
@ -141,7 +143,11 @@ if (isset($_POST['start'])) {
}
/* Check reply */
try {
$message = new OpenID_Message($queryString, OpenID_Message::FORMAT_HTTP);
} catch (Exception $e) {
die_error($e);
}
$id = $message->get('openid.claimed_id');

View File

@ -12,11 +12,11 @@
*/
/* Need to have cookie visible from parent directory */
session_set_cookie_params(0, '/', '', 0);
session_set_cookie_params(0, '/', '', true, true);
/* Create signon session */
$session_name = 'SignonSession';
session_name($session_name);
session_start();
@session_start();
/* Was data posted? */
if (isset($_POST['user'])) {
@ -29,7 +29,7 @@ if (isset($_POST['user'])) {
$_SESSION['PMA_single_signon_cfgupdate'] = array('verbose' => 'Signon test');
$id = session_id();
/* Close that session */
session_write_close();
@session_write_close();
/* Redirect to phpMyAdmin (should use absolute URL here!) */
header('Location: ../index.php');
} else {

View File

@ -1,44 +0,0 @@
# This is a typical file used to enable Swekey hardware authentication.
#
# To activate the Swekey authentication add the following line to your config.inc.php file.
# $cfg['Servers'][$i]['auth_swekey_config'] = '/etc/swekey-pma.conf';
# Then rename this file "swekey-pma.conf" and copy it to the /etc directory.
# Add all the Swekey ids you want to grant access to in the file.
# After each Swekey id put the corresponding user name.
#
# If you don't know the id of a Swekey just visit http://www.swekey.com?sel=support
# while your Swekey is connected.
#
# If you need to purchase a Swekey please visit http://phpmyadmin.net/auth_key
# since this link provides funding to PhpMyAdmin.
#
0000000000000000000000000000763A:root
000000000000000000000000000089E4:steve
0000000000000000000000000000231E:scott
#
# It is recommended to include the following lines to contact the
# authentication servers in SSL mode.
#
SERVER_CHECK=https://auth-check-ssl.musbe.net
SERVER_RNDTOKEN=https://auth-rnd-gen-ssl.musbe.net
SERVER_STATUS=https://auth-status-ssl.musbe.net
#
# The path of the root certificate file used to ensure a secure
# communication with the authentication servers in SSL mode.
# If not specified, will use musbe-ca.crt found in your
# phpMyAdmin/libraries/auth/swekey.
#
#CA_FILE=/var/http-root/phpmyadmin/libraries/auth/swekey/musbe-ca.crt
#
# If your server receives many login requests, you can enable the random
# token caching to accelerate the authentication process.
# Token caching is enabled by default.
#
#ENABLE_TOKEN_CACHE=0

View File

@ -10,59 +10,18 @@
define('PMA_MINIMUM_COMMON', true);
require_once 'libraries/common.inc.php';
/* For chart exporting */
if (isset($_REQUEST['filename']) && isset($_REQUEST['image'])) {
$allowed = array(
'image/png' => 'png',
'image/svg+xml' => 'svg',
);
/* Check whether MIME type is allowed */
if (! isset($allowed[$_REQUEST['type']])) {
PMA_fatalError(__('Invalid export type'));
}
/*
* Check file name to match mime type and not contain new lines
* to prevent response splitting.
*/
$extension = $allowed[$_REQUEST['type']];
$valid_match = '/^[^\n\r]*\.' . $extension . '$/';
if (! preg_match($valid_match, $_REQUEST['filename'])) {
if (! preg_match('/^[^\n\r]*$/', $_REQUEST['filename'])) {
/* Filename is unsafe, discard it */
$filename = 'download.' . $extension;
} else {
/* Add extension */
$filename = $_REQUEST['filename'] . '.' . $extension;
}
} else {
/* Filename from request should be safe here */
$filename = $_REQUEST['filename'];
}
/* Decode data */
if ($extension != 'svg') {
$data = substr($_REQUEST['image'], strpos($_REQUEST['image'], ',') + 1);
$data = base64_decode($data);
} else {
$data = $_REQUEST['image'];
}
/* Send download header */
PMA_downloadHeader($filename, $_REQUEST['type'], strlen($data));
/* Send data */
echo $data;
} else if (isset($_REQUEST['monitorconfig'])) {
if (isset($_REQUEST['monitorconfig'])) {
/* For monitor chart config export */
PMA_downloadHeader('monitor.cfg', 'application/force-download');
PMA_downloadHeader('monitor.cfg', 'application/json; charset=UTF-8');
header('X-Content-Type-Options: nosniff');
echo urldecode($_REQUEST['monitorconfig']);
} else if (isset($_REQUEST['import'])) {
/* For monitor chart config import */
header('Content-type: text/plain');
header('Content-Type: application/json; charset=UTF-8');
header('X-Content-Type-Options: nosniff');
if (!file_exists($_FILES['file']['tmp_name'])) {
exit();
}

View File

@ -6,6 +6,11 @@
* @package PhpMyAdmin
*/
/* Enable LOAD DATA LOCAL INFILE for LDI plugin */
if (isset($_POST['format']) && $_POST['format'] == 'ldi') {
define('PMA_ENABLE_LDI', 1);
}
/**
* Get the variables sent or posted to this script and a core script
*/
@ -338,6 +343,15 @@ if (! empty($local_import_file) && ! empty($cfg['UploadDir'])) {
$import_file = PMA_Util::userDir($cfg['UploadDir'])
. $local_import_file;
/*
* Do not allow symlinks to avoid security issues
* (user can create symlink to file he can not access,
* but phpMyAdmin can).
*/
if (is_link($import_file)) {
$import_file = 'none';
}
} elseif (empty($import_file) || ! is_uploaded_file($import_file)) {
$import_file = 'none';
}
@ -474,8 +488,9 @@ if ($GLOBALS['PMA_recoding_engine'] != PMA_CHARSET_NONE && isset($charset_of_fil
// Something to skip?
if (! $error && isset($skip)) {
$skip = intval($skip);
$original_skip = $skip;
while ($skip > 0) {
while ($skip > 0 && ! $finished) {
PMA_importGetNextChunk($skip < $read_limit ? $skip : $read_limit);
// Disable read progresivity, otherwise we eat all memory!
$read_multiply = 1;

View File

@ -269,7 +269,7 @@ if ($server > 0 && $GLOBALS['cfg']['ShowServerInfo']) {
echo ' </div>';
}
if ($GLOBALS['cfg']['ShowServerInfo'] || $GLOBALS['cfg']['ShowPhpInfo']) {
if ($GLOBALS['cfg']['ShowServerInfo']) {
echo '<div class="group">';
echo '<h2>' . __('Web server') . '</h2>';
echo '<ul>';
@ -300,15 +300,6 @@ if ($GLOBALS['cfg']['ShowServerInfo'] || $GLOBALS['cfg']['ShowPhpInfo']) {
}
}
if ($cfg['ShowPhpInfo']) {
PMA_printListItem(
__('Show PHP information'),
'li_phpinfo',
'phpinfo.php?' . $common_url_query,
null,
'_blank'
);
}
echo ' </ul>';
echo ' </div>';
}
@ -317,7 +308,7 @@ echo '<div class="group pmagroup">';
echo '<h2>phpMyAdmin</h2>';
echo '<ul>';
$class = null;
// We rely on CSP to allow access to http://www.phpmyadmin.net, but IE lacks
// We rely on CSP to allow access to https://www.phpmyadmin.net, but IE lacks
// support here and does not allow request to http once using https.
if ($GLOBALS['cfg']['VersionCheck']
&& (! $GLOBALS['PMA_Config']->get('is_https') || PMA_USR_BROWSER_AGENT != 'IE')
@ -343,7 +334,7 @@ PMA_printListItem(
PMA_printListItem(
__('Wiki'),
'li_pma_wiki',
PMA_linkURL('http://wiki.phpmyadmin.net/'),
PMA_linkURL('https://wiki.phpmyadmin.net/'),
null,
'_blank'
);
@ -352,21 +343,21 @@ PMA_printListItem(
PMA_printListItem(
__('Official Homepage'),
'li_pma_homepage',
PMA_linkURL('http://www.phpMyAdmin.net/'),
PMA_linkURL('http://www.phpmyadmin.net/'),
null,
'_blank'
);
PMA_printListItem(
__('Contribute'),
'li_pma_contribute',
PMA_linkURL('http://www.phpmyadmin.net/home_page/improve.php'),
PMA_linkURL('https://www.phpmyadmin.net/home_page/improve.php'),
null,
'_blank'
);
PMA_printListItem(
__('Get support'),
'li_pma_support',
PMA_linkURL('http://www.phpmyadmin.net/home_page/support.php'),
PMA_linkURL('https://www.phpmyadmin.net/home_page/support.php'),
null,
'_blank'
);
@ -447,13 +438,22 @@ if ($GLOBALS['cfg']['LoginCookieStore'] != 0
/**
* Check if user does not have defined blowfish secret and it is being used.
*/
if (! empty($_SESSION['auto_blowfish_secret'])
&& empty($GLOBALS['cfg']['blowfish_secret'])
) {
if (! empty($_SESSION['encryption_key'])) {
if (empty($GLOBALS['cfg']['blowfish_secret'])) {
trigger_error(
__('The configuration file now needs a secret passphrase (blowfish_secret).'),
__(
'The configuration file now needs a secret passphrase (blowfish_secret).'
),
E_USER_WARNING
);
} elseif (strlen($GLOBALS['cfg']['blowfish_secret']) < 32) {
trigger_error(
__(
'The secret passphrase in configuration (blowfish_secret) is too short.'
),
E_USER_WARNING
);
}
}
/**
@ -565,7 +565,7 @@ if (file_exists('libraries/language_stats.inc.php')) {
&& $GLOBALS['language_stats'][$lang] < $cfg['TranslationWarningThreshold']
) {
trigger_error(
'You are using an incomplete translation, please help to make it better by [a@http://www.phpmyadmin.net/home_page/improve.php#translate@_blank]contributing[/a].',
'You are using an incomplete translation, please help to make it better by [a@https://www.phpmyadmin.net/home_page/improve.php#translate@_blank]contributing[/a].',
E_USER_NOTICE
);
}
@ -598,6 +598,9 @@ function PMA_printListItem($name, $id = null, $url = null, $mysql_help_page = nu
echo '<a href="' . $url . '"';
if (null !== $target) {
echo ' target="' . $target . '"';
if ($target == '_blank') {
echo ' rel="noopener noreferrer"';
}
}
if (null != $a_id) {
echo ' id="' . $a_id .'"';

View File

@ -711,12 +711,20 @@ AJAX.setUrlHash = (function (jQuery, window) {
/**
* Start initialisation
*/
if (window.location.hash.substring(0, 8) == '#PMAURL-') {
var urlhash = window.location.hash;
if (urlhash.substring(0, 8) == '#PMAURL-') {
// We have a valid hash, let's redirect the user
// to the page that it's pointing to
window.location = window.location.hash.substring(
window.location.hash.indexOf(':') + 1
var colon_position = urlhash.indexOf(':');
var questionmark_position = urlhash.indexOf('?');
if (colon_position != -1 && questionmark_position != -1 && colon_position < questionmark_position) {
var hash_url = urlhash.substring(colon_position + 1, questionmark_position);
if (PMA_gotoWhitelist.indexOf(hash_url) != -1) {
window.location = urlhash.substring(
colon_position + 1
);
}
}
} else {
// We don't have a valid hash, so we'll set it up
// when the page finishes loading
@ -801,8 +809,8 @@ $(document).ajaxError(function(event, request, settings){
PMA_ajaxShowMessage(
'<div class="error">'
+ PMA_messages['strErrorProcessingRequest']
+ '<div>' + errorCode + '</div>'
+ '<div>' + errorText + '</div>'
+ '<div>' + escapeHtml(errorCode) + '</div>'
+ '<div>' + escapeHtml(errorText) + '</div>'
+ '</div>',
false
);

View File

@ -556,8 +556,8 @@ AJAX.registerOnload('config.js', function() {
var tab_check_fnc = function() {
if (location.hash != prev_hash) {
prev_hash = location.hash;
if (location.hash.match(/^#tab_.+/) && $('#' + location.hash.substr(5)).length) {
setTab(location.hash.substr(5));
if (prev_hash.match(/^#tab_[a-zA-Z0-9_]+$/) && $('#' + prev_hash.substr(5)).length) {
setTab(prev_hash.substr(5));
}
}
};

View File

@ -77,14 +77,31 @@ function suggestPassword(passwd_form)
// restrict the password to just letters and numbers to avoid problems:
// "editors and viewers regard the password as multiple words and
// things like double click no longer work"
var pwchars = "abcdefhjmnpqrstuvwxyz23456789ABCDEFGHJKLMNPQRSTUVWYXZ";
var pwchars = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWYXZ";
var passwordlength = 16; // do we want that to be dynamic? no, keep it simple :)
var passwd = passwd_form.generated_pw;
var randomWords = new Int32Array(passwordlength);
passwd.value = '';
for (var i = 0; i < passwordlength; i++ ) {
passwd.value += pwchars.charAt( Math.floor( Math.random() * pwchars.length ) );
// First we're going to try to use a built-in CSPRNG
if (window.crypto && window.crypto.getRandomValues) {
window.crypto.getRandomValues(randomWords);
}
// Because of course IE calls it msCrypto instead of being standard
else if (window.msCrypto && window.msCrypto.getRandomValues) {
window.msCrypto.getRandomValues(randomWords);
} else {
// Fallback to Math.random
for (var i = 0; i < passwordlength; i++) {
randomWords[i] = Math.floor(Math.random() * pwchars.length);
}
}
for (var i = 0; i < passwordlength; i++) {
passwd.value += pwchars.charAt(Math.abs(randomWords[i]) % pwchars.length);
}
passwd_form.text_pma_pw.value = passwd.value;
passwd_form.text_pma_pw2.value = passwd.value;
return true;
@ -1358,7 +1375,7 @@ AJAX.registerOnload('functions.js', function() {
var $inner_sql = $(this).parent().prev().find('.inner_sql');
var old_text = $inner_sql.html();
var new_content = "<textarea name=\"sql_query_edit\" id=\"sql_query_edit\">" + sql_query + "</textarea>\n";
var new_content = "<textarea name=\"sql_query_edit\" id=\"sql_query_edit\">" + escapeHtml(sql_query) + "</textarea>\n";
new_content += "<input type=\"submit\" id=\"sql_query_edit_save\" class=\"button btnSave\" value=\"" + PMA_messages['strGo'] + "\"/>\n";
new_content += "<input type=\"button\" id=\"sql_query_edit_discard\" class=\"button btnDiscard\" value=\"" + PMA_messages['strCancel'] + "\"/>\n";
var $editor_area = $('div#inline_editor');
@ -2550,7 +2567,7 @@ AJAX.registerOnload('functions.js', function() {
} else {
var title = PMA_messages['enum_columnVals'].replace(
/%s/,
'"' + decodeURIComponent(colname) + '"'
'"' + escapeHtml(decodeURIComponent(colname)) + '"'
);
}
// Get the values as a string
@ -3178,7 +3195,16 @@ AJAX.registerOnload('functions.js', function() {
* Load version information asynchronously.
*/
if ($('li.jsversioncheck').length > 0) {
$.getJSON('version_check.php', {}, PMA_current_version);
$.ajax({
dataType: "json",
url: 'version_check.php',
method: "POST",
data: {
"server": PMA_commonParams.get('server'),
"token": PMA_commonParams.get('token'),
},
success: PMA_current_version
});
}
if ($('#is_git_revision').length > 0) {
@ -3368,7 +3394,7 @@ AJAX.registerOnload('functions.js', function() {
var question = PMA_messages.strDropTableStrongWarning + ' ';
question += $.sprintf(
PMA_messages.strDoYouReally,
'DROP TABLE ' + PMA_commonParams.get('table')
'DROP TABLE ' + escapeHtml(PMA_commonParams.get('table'))
);
$(this).PMA_confirm(question, $(this).attr('href'), function(url) {
@ -3401,7 +3427,7 @@ AJAX.registerOnload('functions.js', function() {
var question = PMA_messages.strTruncateTableStrongWarning + ' ';
question += $.sprintf(
PMA_messages.strDoYouReally,
'TRUNCATE ' + PMA_commonParams.get('table')
'TRUNCATE ' + escapeHtml(PMA_commonParams.get('table'))
);
$(this).PMA_confirm(question, $(this).attr('href'), function(url) {
PMA_ajaxShowMessage(PMA_messages['strProcessingRequest']);

View File

@ -101,15 +101,15 @@ function PMA_getImage(image, alternate, attributes) {
}
// set alt
if (attributes.alt != undefined) {
retval.attr('alt', attributes.alt);
retval.attr('alt', escapeHtml(attributes.alt));
} else {
retval.attr('alt', alternate);
retval.attr('alt', escapeHtml(alternate));
}
// set title
if (attributes.title != undefined) {
retval.attr('title', attributes.title);
retval.attr('title', escapeHtml(attributes.title));
} else {
retval.attr('title', alternate);
retval.attr('title', escapeHtml(alternate));
}
// set src
var klass = image.replace('.gif', '').replace('.png', '');

View File

@ -14,7 +14,8 @@ header('Content-Type: text/javascript; charset=UTF-8');
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 3600) . ' GMT');
if (! empty($_GET['scripts']) && is_array($_GET['scripts'])) {
foreach ($_GET['scripts'] as $script) {
// Only up to 10 scripts as this is what we generate
foreach (array_slice($_GET['scripts'], 0, 10) as $script) {
// Sanitise filename
$script_name = 'js';
$path = explode("/", $script);

View File

@ -996,7 +996,7 @@ AJAX.registerOnload('server_status_monitor.js', function() {
label: $('#variableInput').val().replace(/_/g, " ")
};
newChart.series.push(newSeries);
$('#seriesPreview').append('- ' + newSeries.label + str + '<br/>');
$('#seriesPreview').append('- ' + escapeHtml(newSeries.label + str) + '<br/>');
newChart.nodes.push(serie);
$('#variableInput').val('');
$('input[name="differentialValue"]').prop('checked', true);
@ -1991,7 +1991,7 @@ AJAX.registerOnload('server_status_monitor.js', function() {
case 'user_host':
return value.replace(/(\[.*?\])+/g, '');
}
return value;
return escapeHtml(value);
};
for (var i = 0, l = rows.length; i < l; i++) {
@ -2144,7 +2144,7 @@ AJAX.registerOnload('server_status_monitor.js', function() {
for (var i = 0, l = data.explain.length; i < l; i++) {
explain += '<div class="explain-' + i + '"' + (i>0? 'style="display:none;"' : '' ) + '>';
$.each(data.explain[i], function(key, value) {
value = (value == null)?'null':value;
value = (value == null)?'null': escapeHtml(value);
if (key == 'type' && value.toLowerCase() == 'all') {
value = '<span class="attention">' + value + '</span>';

View File

@ -103,7 +103,7 @@ AJAX.registerOnload('sql.js', function() {
// Delete row from SQL results
$('a.delete_row.ajax').click(function (e) {
e.preventDefault();
var question = $.sprintf(PMA_messages['strDoYouReally'], $(this).closest('td').find('div').text());
var question = $.sprintf(PMA_messages['strDoYouReally'], escapeHtml($(this).closest('td').find('div').text()));
var $link = $(this);
$link.PMA_confirm(question, $link.attr('href'), function (url) {
$msgbox = PMA_ajaxShowMessage();

View File

@ -201,7 +201,7 @@ function drawChart() {
var columnNames = [];
$('select[name="chartXAxis"] option').each(function() {
columnNames.push($(this).text());
columnNames.push(escapeHtml($(this).text()));
});
try {
currentChart = PMA_queryChart(chart_data, columnNames, currentSettings);
@ -260,7 +260,7 @@ function PMA_queryChart(data, columnNames, settings) {
},
axes : {
xaxis : {
label : settings.xaxisLabel
label : escapeHtml(settings.xaxisLabel)
},
yaxis : {
label : settings.yaxisLabel

View File

@ -144,6 +144,7 @@ AJAX.registerOnload('tbl_structure.js', function() {
* @var curr_column_name String containing name of the field referred to by {@link curr_row}
*/
var curr_column_name = $curr_row.children('th').children('label').text();
curr_column_name = escapeHtml(curr_column_name);
/**
* @var $after_field_item Corresponding entry in the 'After' field.
*/

31
js/whitelist.php Normal file
View File

@ -0,0 +1,31 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Exporting of $goto_whitelist from PHP to Javascript
*
* @package PhpMyAdmin
*/
chdir('..');
// Send correct type:
header('Content-Type: text/javascript; charset=UTF-8');
// Cache output in client - the nocache query parameter makes sure that this
// file is reloaded when config changes
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 3600) . ' GMT');
// Avoid loading the full common.inc.php because this would add many
// non-js-compatible stuff like DOCTYPE
define('PMA_MINIMUM_COMMON', true);
require_once './libraries/common.inc.php';
// Close session early as we won't write anything there
session_write_close();
echo "var PMA_gotoWhitelist = new Array();\n";
$i = -1;
foreach ($GLOBALS['goto_whitelist'] as $one_whitelist) {
$i++;
echo 'PMA_gotoWhitelist[' . $i . ']="' . $one_whitelist . '";' . "\n";
}
?>

View File

@ -102,7 +102,7 @@ class PMA_Config
*/
function checkSystem()
{
$this->set('PMA_VERSION', '4.0.10-dev');
$this->set('PMA_VERSION', '4.0.10.20');
/**
* @deprecated
*/
@ -716,8 +716,6 @@ class PMA_Config
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_USERAGENT, 'phpMyAdmin/' . PMA_VERSION);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
@ -1293,7 +1291,7 @@ class PMA_Config
$pma_absolute_uri .= '@';
}
// Add hostname
$pma_absolute_uri .= $url['host'];
$pma_absolute_uri .= urlencode($url['host']);
// Add port, if it not the default one
if (! empty($url['port'])
&& (($url['scheme'] == 'http' && $url['port'] != 80)
@ -1717,7 +1715,7 @@ class PMA_Config
// for the case when there is no config file (this is supported)
if (empty($current_size)) {
if (isset($_COOKIE['pma_fontsize'])) {
$current_size = $_COOKIE['pma_fontsize'];
$current_size = htmlspecialchars($_COOKIE['pma_fontsize']);
} else {
$current_size = '82%';
}

View File

@ -203,7 +203,10 @@ class PMA_DbQbe
// sets row count
$rows = PMA_ifSetOr($_REQUEST['rows'], 0, 'numeric');
$criteriaRowAdd = PMA_ifSetOr($_REQUEST['criteriaRowAdd'], 0, 'numeric');
$this->_criteria_row_count = max($rows + $criteriaRowAdd, 0);
$this->_criteria_row_count = min(
max($rows + $criteriaRowAdd, 0),
100
);
$this->_criteriaColumnInsert = PMA_ifSetOr(
$_REQUEST['criteriaColumnInsert'],

View File

@ -277,7 +277,7 @@ class PMA_DbSearch
// Gets the SQL statements
$newsearchsqls = $this->_getSearchSqls($each_table);
// Executes the "COUNT" statement
$res_cnt = PMA_DBI_fetch_value($newsearchsqls['select_count']);
$res_cnt = intval(PMA_DBI_fetch_value($newsearchsqls['select_count']));
$num_search_result_total += $res_cnt;
// Gets the result row's HTML for a table
$html_output .= $this->_getResultsRow(
@ -340,7 +340,8 @@ class PMA_DbSearch
$browse_result_path = 'sql.php' . PMA_generate_common_url($this_url_params);
$html_output .= '<td><a name="browse_search" href="'
. $browse_result_path . '" onclick="loadResult(\''
. $browse_result_path . '\',\'' . $each_table . '\',\''
. $browse_result_path . '\',\''
. PMA_escapeJsString(htmlspecialchars($each_table)) . '\',\''
. PMA_generate_common_url($GLOBALS['db'], $each_table) . '\''
. ');return false;" >'
. __('Browse') . '</a></td>';
@ -349,10 +350,10 @@ class PMA_DbSearch
$html_output .= '<td><a name="delete_search" href="'
. $delete_result_path . '" onclick="deleteResult(\''
. $delete_result_path . '\' , \''
. sprintf(
. PMA_escapeJsString(sprintf(
__('Delete the matches for the %s table?'),
htmlspecialchars($each_table)
)
))
. '\');return false;">'
. __('Delete') . '</a></td>';
} else {

View File

@ -371,14 +371,18 @@ class PMA_Error extends PMA_Message
* prevent path disclusore in error message,
* and make users feel save to submit error reports
*
* @param string $dest path to be shorten
* @param string $path path to be shorten
*
* @return string shortened path
* @static
*/
static function relPath($dest)
static function relPath($path)
{
$dest = realpath($dest);
$dest = @realpath($path);
if ($dest === false) {
return basename($path);
}
if (substr(PHP_OS, 0, 3) == 'WIN') {
$path_separator = '\\';

View File

@ -428,6 +428,11 @@ class PMA_File
$this->setName(
PMA_Util::userDir($GLOBALS['cfg']['UploadDir']) . PMA_securePath($name)
);
if (is_link($this->getName())) {
$this->_error_message = __('File is a symbolic link');
$this->setName(null);
return false;
}
if (! $this->isReadable()) {
$this->_error_message = __('File could not be read');
$this->setName(null);

View File

@ -146,7 +146,16 @@ class PMA_Header
*/
private function _addDefaultScripts()
{
// Localised strings
$params = array('lang' => $GLOBALS['lang']);
if (isset($GLOBALS['db'])) {
$params['db'] = $GLOBALS['db'];
}
$this->_scripts->addFile('jquery/jquery-1.8.3.min.js');
$this->_scripts->addFile(
'whitelist.php' . PMA_generate_common_url($params), false, true
);
$this->_scripts->addFile('ajax.js');
$this->_scripts->addFile('keyhandler.js');
$this->_scripts->addFile('jquery/jquery-ui-1.9.2.custom.min.js');
@ -169,11 +178,6 @@ class PMA_Header
// Here would not be a good place to add CodeMirror because
// the user preferences have not been merged at this point
// Localised strings
$params = array('lang' => $GLOBALS['lang']);
if (isset($GLOBALS['db'])) {
$params['db'] = $GLOBALS['db'];
}
$this->_scripts->addFile('messages.php' . PMA_generate_common_url($params));
// Append the theme id to this url to invalidate
// the cache on a theme change. Though this might be
@ -461,41 +465,56 @@ class PMA_Header
'X-Frame-Options: DENY'
);
}
header(
"Content-Security-Policy: default-src 'self' "
. $GLOBALS['cfg']['CSPAllow'] . ';'
. "script-src 'self' 'unsafe-inline' 'unsafe-eval' "
. $GLOBALS['cfg']['CSPAllow'] . ';'
. ";"
. "style-src 'self' 'unsafe-inline' "
. $GLOBALS['cfg']['CSPAllow']
. ";"
. "referrer no-referrer;"
. "img-src 'self' data: "
. $GLOBALS['cfg']['CSPAllow']
. ($https ? "" : $mapTilesUrls)
. ";"
);
header(
"X-Content-Security-Policy: default-src 'self' "
. $GLOBALS['cfg']['CSPAllow'] . ';'
. "options inline-script eval-script;"
. "img-src 'self' data: "
. "referrer no-referrer;"
. $GLOBALS['cfg']['CSPAllow']
. ($https ? "" : $mapTilesUrls)
. ";"
);
if (PMA_USR_BROWSER_AGENT == 'SAFARI'
&& PMA_USR_BROWSER_VER < '6.0.0'
) {
header(
"X-WebKit-CSP: allow 'self' "
. $GLOBALS['cfg']['CSPAllow'] . ';'
. "options inline-script eval-script;"
. "img-src 'self' data: "
. $GLOBALS['cfg']['CSPAllow']
. ($https ? "" : $mapTilesUrls)
. ";"
);
} else {
header(
"X-WebKit-CSP: default-src 'self' "
. $GLOBALS['cfg']['CSPAllow'] . ';'
. "script-src 'self' "
. $GLOBALS['cfg']['CSPAllow']
. " 'unsafe-inline' 'unsafe-eval';"
. "style-src 'self' 'unsafe-inline';"
. "style-src 'self' 'unsafe-inline' "
. ';'
. "referrer no-referrer;"
. "img-src 'self' data: "
. $GLOBALS['cfg']['CSPAllow']
. ($https ? "" : $mapTilesUrls)
. ";"
);
header(
"X-Content-Security-Policy: default-src 'self' "
. $GLOBALS['cfg']['CSPAllow'] . ';'
. "options inline-script eval-script;"
. "referrer no-referrer;"
. "img-src 'self' data: "
. $GLOBALS['cfg']['CSPAllow']
. ($https ? "" : $mapTilesUrls)
. ";"
);
}
}
PMA_noCacheHeader();
if (! defined('IS_TRANSFORMATION_WRAPPER') && ! defined('TESTSUITE')) {
@ -529,6 +548,7 @@ class PMA_Header
private function _getMetaTags()
{
$retval = '<meta charset="utf-8" />';
$retval .= '<meta name="referrer" content="no-referrer" />';
$retval .= '<meta name="robots" content="noindex,nofollow" />';
$retval .= '<meta http-equiv="X-UA-Compatible" content="IE=Edge">';
if (! $GLOBALS['cfg']['AllowThirdPartyFraming']) {

View File

@ -9,6 +9,8 @@ if (! defined('PHPMYADMIN')) {
exit;
}
require_once './libraries/Util.class.php';
/**
* Output buffering wrapper class
*
@ -94,7 +96,7 @@ class PMA_OutputBuffering
if (! defined('TESTSUITE')) {
header('X-ob_mode: ' . $this->_mode);
}
register_shutdown_function('PMA_OutputBuffering::stop');
register_shutdown_function(array('PMA_OutputBuffering', 'stop'));
$this->_on = true;
}
}

View File

@ -84,7 +84,7 @@ class PMA_RecentTable
// Read from phpMyAdmin database, if recent tables is not in session
$sql_query
= " SELECT `tables` FROM " . $this->_pmaTable .
" WHERE `username` = '" . $GLOBALS['cfg']['Server']['user'] . "'";
" WHERE `username` = '" . PMA_Util::sqlAddSlashes($GLOBALS['cfg']['Server']['user']) . "'";
$return = array();
$result = PMA_queryAsControlUser($sql_query, false);

View File

@ -66,6 +66,13 @@ class PMA_Response
* @var bool
*/
private $_isAjax;
/**
* Whether response object is disabled
*
* @access private
* @var bool
*/
private $_isDisabled;
/**
* Whether we are servicing an ajax request for a page
* that was fired using the generic page handler in JS.
@ -109,6 +116,7 @@ class PMA_Response
$this->_isSuccess = true;
$this->_isAjax = false;
$this->_isAjaxPage = false;
$this->_isDisabled = false;
if (isset($_REQUEST['ajax_request']) && $_REQUEST['ajax_request'] == true) {
$this->_isAjax = true;
}
@ -181,6 +189,7 @@ class PMA_Response
{
$this->_header->disable();
$this->_footer->disable();
$this->_isDisabled = true;
}
/**
@ -280,6 +289,12 @@ class PMA_Response
*/
private function _ajaxResponse()
{
/* Avoid wrapping in case we're disabled */
if ($this->_isDisabled) {
echo $this->_getDisplay();
return;
}
if (! isset($this->_JSON['message'])) {
$this->_JSON['message'] = $this->_getDisplay();
} else if ($this->_JSON['message'] instanceof PMA_Message) {

View File

@ -50,6 +50,7 @@ class PMA_Scripts
*/
private function _includeFiles($files)
{
$first_dynamic_scripts = "";
$dynamic_scripts = "";
$params = array();
foreach ($files as $value) {
@ -67,15 +68,26 @@ class PMA_Scripts
if ($include) {
$params[] = "scripts[]=" . $value['filename'];
}
} else {
if ($value['before_statics'] === true) {
$first_dynamic_scripts .= "<script type='text/javascript' src='js/" . $value['filename'] . "'></script>";
} else {
$dynamic_scripts .= "<script type='text/javascript' src='js/" . $value['filename'] . "'></script>";
}
}
$static_scripts = sprintf(
"<script type='text/javascript' src='js/get_scripts.js.php?%s'></script>",
implode("&", $params)
}
$static_scripts = '';
// Using chunks of 10 files to avoid too long URLs
$script_chunks = array_chunk($params, 10);
foreach ($script_chunks as $script_chunk) {
$url = 'js/get_scripts.js.php?' . implode('&', $script_chunk);
$static_scripts .= sprintf(
'<script type="text/javascript" src="%s"></script>',
htmlspecialchars($url)
);
return $static_scripts . $dynamic_scripts;
}
return $first_dynamic_scripts . $static_scripts . $dynamic_scripts;
}
/**
@ -97,10 +109,12 @@ class PMA_Scripts
* @param string $filename The name of the file to include
* @param bool $conditional_ie Whether to wrap the script tag in
* conditional comments for IE
* @param bool $before_statics Whether this dynamic script should be
* include before the static ones
*
* @return void
*/
public function addFile($filename, $conditional_ie = false)
public function addFile($filename, $conditional_ie = false, $before_statics = false)
{
$hash = md5($filename);
if (empty($this->_files[$hash])) {
@ -108,7 +122,8 @@ class PMA_Scripts
$this->_files[$hash] = array(
'has_onload' => $has_onload,
'filename' => $filename,
'conditional_ie' => $conditional_ie
'conditional_ie' => $conditional_ie,
'before_statics' => $before_statics
);
}
}

View File

@ -1411,7 +1411,7 @@ class PMA_Table
// Read from phpMyAdmin database
$sql_query = " SELECT `prefs` FROM " . $pma_table
. " WHERE `username` = '" . $GLOBALS['cfg']['Server']['user'] . "'"
. " WHERE `username` = '" . PMA_Util::sqlAddSlashes($GLOBALS['cfg']['Server']['user']) . "'"
. " AND `db_name` = '" . PMA_Util::sqlAddSlashes($this->db_name) . "'"
. " AND `table_name` = '" . PMA_Util::sqlAddSlashes($this->name) . "'";
@ -1435,7 +1435,7 @@ class PMA_Table
$username = $GLOBALS['cfg']['Server']['user'];
$sql_query = " REPLACE INTO " . $pma_table
. " VALUES ('" . $username . "', '" . PMA_Util::sqlAddSlashes($this->db_name)
. " VALUES ('" . PMA_Util::sqlAddSlashes($username) . "', '" . PMA_Util::sqlAddSlashes($this->db_name)
. "', '" . PMA_Util::sqlAddSlashes($this->name) . "', '"
. PMA_Util::sqlAddSlashes(json_encode($this->uiprefs)) . "', NULL)";

View File

@ -307,6 +307,7 @@ EOT;
private function _getEnumSetInputBox($column_index, $criteriaValues,
$column_type, $column_id, $in_zoom_search_edit = false
) {
$column_type = htmlspecialchars($column_type);
$html_output = '';
$value = explode(
', ',
@ -932,7 +933,9 @@ EOT;
$html_output .= '<th>'
. htmlspecialchars($this->_columnNames[$column_index]) . '</th>';
$properties = $this->getColumnProperties($column_index, $column_index);
$html_output .= '<td>' . $properties['type'] . '</td>';
$html_output .= '<td>'
. htmlspecialchars($properties['type'])
. '</td>';
$html_output .= '<td>' . $properties['collation'] . '</td>';
$html_output .= '<td>' . $properties['func'] . '</td>';
$html_output .= '<td>' . $properties['value'] . '</td>';
@ -941,11 +944,13 @@ EOT;
$html_output .= '<tr><td>';
$html_output .= '<input type="hidden"'
. ' name="criteriaColumnNames[' . $column_index . ']"'
. ' value="' . htmlspecialchars($this->_columnNames[$column_index])
. ' value="'
. htmlspecialchars($this->_columnNames[$column_index])
. '" />';
$html_output .= '<input type="hidden"'
. ' name="criteriaColumnTypes[' . $column_index . ']"'
. ' value="' . $this->_columnTypes[$column_index] . '" />';
. ' value="'
. htmlspecialchars($this->_columnTypes[$column_index]) . '" />';
$html_output .= '<input type="hidden"'
. ' name="criteriaColumnCollations[' . $column_index . ']"'
. ' value="' . $this->_columnCollations[$column_index] . '" />';
@ -1012,21 +1017,21 @@ EOT;
$value[$i] = $properties['value'];
}
//Column type
$html_output .= '<td>' . (isset($type[$i]) ? $type[$i] : '') . '</td>';
$html_output .= '<td>' . (isset($type[$i]) ? htmlspecialchars($type[$i]) : '') . '</td>';
//Column Collation
$html_output .= '<td>' . (isset($collation[$i]) ? $collation[$i] : '')
. '</td>';
//Select options for column operators
$html_output .= '<td>' . (isset($func[$i]) ? $func[$i] : '') . '</td>';
//Inputbox for search criteria value
$html_output .= '<td>' . (isset($value[$i]) ? $value[$i] : '') . '</td>';
$html_output .= '<td>' . (isset($value[$i]) ? htmlspecialchars($value[$i]) : '') . '</td>';
$html_output .= '</tr>';
//Displays hidden fields
$html_output .= '<tr><td>';
$html_output .= '<input type="hidden" name="criteriaColumnTypes[' . $i . ']"'
. ' id="types_' . $i . '" ';
if (isset($_POST['criteriaColumnTypes'][$i])) {
$html_output .= 'value="' . $_POST['criteriaColumnTypes'][$i] . '" ';
$html_output .= 'value="' . htmlspecialchars($_POST['criteriaColumnTypes'][$i]) . '" ';
}
$html_output .= '/>';
$html_output .= '<input type="hidden" name="criteriaColumnCollations['
@ -1175,7 +1180,7 @@ EOT;
$html_output .= '<center><a href="#" onclick="displayHelp();">'
. __('How to use') . '</a></center>';
$html_output .= '<div id="querydata" style="display:none">'
. json_encode($data) . '</div>';
. htmlspecialchars(json_encode($data)) . '</div>';
$html_output .= '<div id="querychart"></div>';
$html_output .= '<button class="button-reset">'
. __('Reset zoom') . '</button>';

View File

@ -490,9 +490,6 @@ class PMA_Theme
if (!is_null($fs)) {
return $fs;
}
if (isset($_COOKIE['pma_fontsize'])) {
return $_COOKIE['pma_fontsize'];
}
return '82%';
}

View File

@ -230,8 +230,9 @@ class PMA_Tracker
static public function getLogComment()
{
$date = date('Y-m-d H:i:s');
$user = preg_replace('/\s+/', ' ', $GLOBALS['cfg']['Server']['user']);
return "# log " . $date . " " . $GLOBALS['cfg']['Server']['user'] . "\n";
return "# log " . $date . " " . $user . "\n";
}
/**

View File

@ -552,7 +552,7 @@ class PMA_Util
/* Check if we have built local documentation */
if (defined('TESTSUITE')) {
/* Provide consistent URL for testsuite */
return PMA_linkURL('http://docs.phpmyadmin.net/en/latest/' . $url);
return PMA_linkURL('https://docs.phpmyadmin.net/en/latest/' . $url);
} else if (file_exists('doc/html/index.html')) {
if (defined('PMA_SETUP')) {
return '../doc/html/' . $url;
@ -561,7 +561,7 @@ class PMA_Util
}
} else {
/* TODO: Should link to correct branch for released versions */
return PMA_linkURL('http://docs.phpmyadmin.net/en/latest/' . $url);
return PMA_linkURL('https://docs.phpmyadmin.net/en/latest/' . $url);
}
}
@ -2659,7 +2659,7 @@ class PMA_Util
$dir .= '/';
}
return str_replace('%u', $GLOBALS['cfg']['Server']['user'], $dir);
return str_replace('%u', PMA_securePath($GLOBALS['cfg']['Server']['user']), $dir);
}
/**
@ -3150,8 +3150,11 @@ class PMA_Util
// for the case ENUM('&#8211;','&ldquo;')
$displayed_type = htmlspecialchars($printtype);
if (strlen($printtype) > $GLOBALS['cfg']['LimitChars']) {
$displayed_type = '<abbr title="' . $printtype . '">';
$displayed_type .= substr($printtype, 0, $GLOBALS['cfg']['LimitChars']);
$displayed_type = '<abbr title="'
. htmlspecialchars($printtype) . '">';
$displayed_type .= htmlspecialchars(
substr($printtype, 0, $GLOBALS['cfg']['LimitChars'])
);
$displayed_type .= '</abbr>';
}
@ -4148,5 +4151,94 @@ class PMA_Util
. PMA_Util::localisedDate(strtotime($table['Check_time']));
}
}
/**
* Returns the version and date of the latest phpMyAdmin version compatible
* with avilable PHP and MySQL versions
*
* @param array $releases array of information related to each version
*
* @return array containing the version and date of latest compatibel version
*/
public static function getLatestCompatibleVersion($releases)
{
foreach ($releases as $release) {
$phpVersions = $release->php_versions;
$phpConditions = explode(",", $phpVersions);
foreach ($phpConditions as $phpCondition) {
if (! self::evaluateVersionCondition("PHP", $phpCondition)) {
continue 2;
}
}
// We evalute MySQL version constraint if there are only
// one server configured.
if (count($GLOBALS['cfg']['Servers']) == 1) {
$mysqlVersions = $release->mysql_versions;
$mysqlConditions = explode(",", $mysqlVersions);
foreach ($mysqlConditions as $mysqlCondition) {
if (! self::evaluateVersionCondition('MySQL', $mysqlCondition)) {
continue 2;
}
}
}
return array(
'version' => $release->version,
'date' => $release->date,
);
}
// no compatible version
return null;
}
/**
* Checks whether PHP or MySQL version meets supplied version condition
*
* @param string $type PHP or MySQL
* @param string $condition version condition
*
* @return boolean whether the condition is met
*/
public static function evaluateVersionCondition($type, $condition)
{
$operator = null;
$operators = array("<=", ">=", "!=", "<>", "<", ">", "="); // preserve order
foreach ($operators as $oneOperator) {
if (strpos($condition, $oneOperator) === 0) {
$operator = $oneOperator;
$version = substr($condition, strlen($oneOperator));
break;
}
}
$myVersion = null;
if ($type == 'PHP') {
$myVersion = PHP_VERSION;
} elseif ($type == 'MySQL') {
$myVersion = PMA_Util::cacheGet('PMA_MYSQL_STR_VERSION', true);
}
if ($myVersion != null && $operator != null) {
return version_compare($myVersion, $version, $operator);
}
return false;
}
/**
* Converts given (request) paramter to string
*
* @param mixed $value Value to convert
*
* @return string
*/
public static function requestString($value)
{
while (is_array($value) || is_object($value)) {
$value = reset($value);
}
return trim((string)$value);
}
}
?>

View File

@ -166,10 +166,10 @@ function PMA_buildHtmlForDb(
. '" href="server_privileges.php?' . $url_query
. '&amp;checkprivs=' . urlencode($current['SCHEMA_NAME'])
. '" title="'
. sprintf(
__('Check privileges for database &quot;%s&quot;.'),
htmlspecialchars($current['SCHEMA_NAME'])
)
. htmlspecialchars(sprintf(
__('Check privileges for database "%s".'),
$current['SCHEMA_NAME']
))
. '">'
. ' '
. PMA_Util::getIcon('s_rights.png', __('Check Privileges'))

View File

@ -143,7 +143,7 @@ require './libraries/Table.class.php';
*/
require './libraries/Types.class.php';
if (! defined('PMA_MINIMUM_COMMON')) {
if (! defined('PMA_MINIMUM_COMMON') || defined('PMA_SETUP')) {
/**
* common functions
*/
@ -235,7 +235,7 @@ unset($key, $value, $variables_whitelist);
* so we now check if a subform is submitted
*/
$__redirect = null;
if (isset($_POST['usesubform'])) {
if (isset($_POST['usesubform']) && ! defined('PMA_MINIMUM_COMMON')) {
// if a subform is present and should be used
// the rest of the form is deprecated
$subform_id = key($_POST['usesubform']);
@ -346,6 +346,7 @@ if (isset($_COOKIE)
if ($GLOBALS['PMA_Config']->get('ForceSSL')
&& ! $GLOBALS['PMA_Config']->get('is_https')
) {
require './libraries/select_lang.lib.php';
// grab SSL URL
$url = $GLOBALS['PMA_Config']->getSSLUri();
// Actually redirect
@ -400,7 +401,6 @@ $goto_whitelist = array(
'index.php',
'pdf_pages.php',
'pdf_schema.php',
//'phpinfo.php',
'querywindow.php',
'server_binlog.php',
'server_collations.php',
@ -482,7 +482,7 @@ if (PMA_checkPageValidity($_REQUEST['back'], $goto_whitelist)) {
*/
$token_mismatch = true;
if (PMA_isValid($_REQUEST['token'])) {
$token_mismatch = ($_SESSION[' PMA_token '] != $_REQUEST['token']);
$token_mismatch = ! hash_equals($_SESSION[' PMA_token '], $_REQUEST['token']);
}
if ($token_mismatch) {
@ -503,7 +503,9 @@ if ($token_mismatch) {
/* Needed to send the correct reply */
'ajax_request',
/* Permit to log out even if there is a token mismatch */
'old_usr'
'old_usr',
/* url.php */
'url',
);
/**
* Allow changing themes in test/theme.php
@ -866,6 +868,9 @@ if (! defined('PMA_MINIMUM_COMMON')) {
. ' ' . $cfg['Server']['auth_type']
);
}
if (isset($_REQUEST['pma_password']) && strlen($_REQUEST['pma_password']) > 256) {
$_REQUEST['pma_password'] = substr($_REQUEST['pma_password'], 0, 256);
}
include_once './libraries/plugins/auth/' . $auth_class . '.class.php';
// todo: add plugin manager
$plugin_manager = null;
@ -974,6 +979,8 @@ if (! defined('PMA_MINIMUM_COMMON')) {
$controllink = $userlink;
}
$auth_plugin->storeUserCredentials();
/* Log success */
PMA_log_user($cfg['Server']['user']);

View File

@ -207,14 +207,6 @@ $cfg['Servers'][$i]['auth_type'] = 'cookie';
*/
$cfg['Servers'][$i]['auth_http_realm'] = '';
/**
* File containing Swekey ids and login names (see /contrib);
* leave empty to deactivate Swekey hardware authentication
*
* @global string $cfg['Servers'][$i]['auth_swekey_config']
*/
$cfg['Servers'][$i]['auth_swekey_config'] = '';
/**
* MySQL user
*
@ -912,13 +904,6 @@ $cfg['NavigationTreeDefaultTabTable'] = 'tbl_structure.php';
*/
$cfg['ShowStats'] = true;
/**
* show PHP info link
*
* @global boolean $cfg['ShowPhpInfo']
*/
$cfg['ShowPhpInfo'] = false;
/**
* show MySQL server and web server information
*

View File

@ -486,21 +486,6 @@ class ConfigFile
}
}
/**
* Returns config file path, relative to phpMyAdmin's root path
*
* @return string
*/
public function getFilePath()
{
// Load paths
if (!defined('SETUP_CONFIG_FILE')) {
include_once './libraries/vendor_config.php';
}
return SETUP_CONFIG_FILE;
}
/**
* Returns configuration array (full, multidimensional format)
*

View File

@ -562,11 +562,13 @@ class FormDisplay
// cast variables to correct type
switch ($type) {
case 'double':
$_POST[$key] = PMA_Util::requestString($_POST[$key]);
settype($_POST[$key], 'float');
break;
case 'boolean':
case 'integer':
if ($_POST[$key] !== '') {
$_POST[$key] = PMA_Util::requestString($_POST[$key]);
settype($_POST[$key], $type);
}
break;
@ -583,7 +585,7 @@ class FormDisplay
break;
case 'string':
case 'short_string':
$_POST[$key] = trim($_POST[$key]);
$_POST[$key] = PMA_Util::requestString($_POST[$key]);
break;
case 'array':
// eliminate empty values and ensure we have an array
@ -592,7 +594,7 @@ class FormDisplay
: explode("\n", $_POST[$key]);
$_POST[$key] = array();
foreach ($post_values as $v) {
$v = trim($v);
$v = PMA_Util::requestString($v);
if ($v !== '') {
$_POST[$key][] = $v;
}
@ -708,7 +710,7 @@ class FormDisplay
if ($test == 'Export') {
$opt_name = substr($opt_name, 7);
}
return PMA_linkURL('http://wiki.phpmyadmin.net/pma/Config#' . $opt_name);
return PMA_linkURL('https://wiki.phpmyadmin.net/pma/Config#' . $opt_name);
}
/**

View File

@ -11,7 +11,7 @@
*/
if (!function_exists('__')) {
PMA_fatalError('Bad invocation!');
exit();
}
$strConfigAllowArbitraryServer_desc = __('If enabled user can enter any MySQL server in login form for cookie auth');
@ -373,11 +373,9 @@ $strConfigServers_AllowNoPassword_name = __('Allow logins without a password');
$strConfigServers_AllowRoot_name = __('Allow root login');
$strConfigServers_auth_http_realm_desc = __('HTTP Basic Auth Realm name to display when doing HTTP Auth');
$strConfigServers_auth_http_realm_name = __('HTTP Realm');
$strConfigServers_auth_swekey_config_desc = __('The path for the config file for [a@http://swekey.com]SweKey hardware authentication[/a] (not located in your document root; suggested: /etc/swekey.conf)');
$strConfigServers_auth_swekey_config_name = __('SweKey config file');
$strConfigServers_auth_type_desc = __('Authentication method to use');
$strConfigServers_auth_type_name = __('Authentication type');
$strConfigServers_bookmarktable_desc = __('Leave blank for no [a@http://wiki.phpmyadmin.net/pma/bookmark]bookmark[/a] support, suggested: [kbd]pma__bookmark[/kbd]');
$strConfigServers_bookmarktable_desc = __('Leave blank for no [a@https://wiki.phpmyadmin.net/pma/bookmark]bookmark[/a] support, suggested: [kbd]pma__bookmark[/kbd]');
$strConfigServers_bookmarktable_name = __('Bookmark table');
$strConfigServers_column_info_desc = __('Leave blank for no column comments/mime types, suggested: [kbd]pma__column_info[/kbd]');
$strConfigServers_column_info_name = __('Column information table');
@ -386,7 +384,7 @@ $strConfigServers_compress_name = __('Compress connection');
$strConfigServers_connect_type_desc = __('How to connect to server, keep [kbd]tcp[/kbd] if unsure');
$strConfigServers_connect_type_name = __('Connection type');
$strConfigServers_controlpass_name = __('Control user password');
$strConfigServers_controluser_desc = __('A special MySQL user configured with limited permissions, more information available on [a@http://wiki.phpmyadmin.net/pma/controluser]wiki[/a]');
$strConfigServers_controluser_desc = __('A special MySQL user configured with limited permissions, more information available on [a@https://wiki.phpmyadmin.net/pma/controluser]wiki[/a]');
$strConfigServers_controluser_name = __('Control user');
$strConfigServers_controlhost_desc = __('An alternate host to hold the configuration storage; leave blank to use the already defined host');
$strConfigServers_controlhost_name = __('Control host');
@ -413,17 +411,17 @@ $strConfigServers_password_desc = __('Leave empty if not using config auth');
$strConfigServers_password_name = __('Password for config auth');
$strConfigServers_pdf_pages_desc = __('Leave blank for no PDF schema support, suggested: [kbd]pma__pdf_pages[/kbd]');
$strConfigServers_pdf_pages_name = __('PDF schema: pages table');
$strConfigServers_pmadb_desc = __('Database used for relations, bookmarks, and PDF features. See [a@http://wiki.phpmyadmin.net/pma/pmadb]pmadb[/a] for complete information. Leave blank for no support. Suggested: [kbd]phpmyadmin[/kbd]');
$strConfigServers_pmadb_desc = __('Database used for relations, bookmarks, and PDF features. See [a@https://wiki.phpmyadmin.net/pma/pmadb]pmadb[/a] for complete information. Leave blank for no support. Suggested: [kbd]phpmyadmin[/kbd]');
$strConfigServers_pmadb_name = __('Database name');
$strConfigServers_port_desc = __('Port on which MySQL server is listening, leave empty for default');
$strConfigServers_port_name = __('Server port');
$strConfigServers_recent_desc = __('Leave blank for no "persistent" recently used tables across sessions, suggested: [kbd]pma__recent[/kbd]');
$strConfigServers_recent_name = __('Recently used table');
$strConfigServers_relation_desc = __('Leave blank for no [a@http://wiki.phpmyadmin.net/pma/relation]relation-links[/a] support, suggested: [kbd]pma__relation[/kbd]');
$strConfigServers_relation_desc = __('Leave blank for no [a@https://wiki.phpmyadmin.net/pma/relation]relation-links[/a] support, suggested: [kbd]pma__relation[/kbd]');
$strConfigServers_relation_name = __('Relation table');
$strConfigServers_ShowDatabasesCommand_desc = __('SQL command to fetch available databases');
$strConfigServers_ShowDatabasesCommand_name = __('SHOW DATABASES command');
$strConfigServers_SignonSession_desc = __('See [a@http://wiki.phpmyadmin.net/pma/auth_types#signon]authentication types[/a] for an example');
$strConfigServers_SignonSession_desc = __('See [a@https://wiki.phpmyadmin.net/pma/auth_types#signon]authentication types[/a] for an example');
$strConfigServers_SignonSession_name = __('Signon session name');
$strConfigServers_SignonURL_name = __('Signon URL');
$strConfigServers_socket_desc = __('Socket on which MySQL server is listening, leave empty for default');
@ -473,8 +471,6 @@ $strConfigShowFunctionFields_desc = __('Display the function fields in edit/inse
$strConfigShowFunctionFields_name = __('Show function fields');
$strConfigShowHint_desc = __('Whether to show hint or not');
$strConfigShowHint_name = __('Show hint');
$strConfigShowPhpInfo_desc = __('Shows link to [a@http://php.net/manual/function.phpinfo.php]phpinfo()[/a] output');
$strConfigShowPhpInfo_name = __('Show phpinfo() link');
$strConfigShowServerInfo_name = __('Show detailed MySQL server information');
$strConfigShowSQL_desc = __('Defines whether SQL queries generated by phpMyAdmin should be displayed');
$strConfigShowSQL_name = __('Show SQL queries');

View File

@ -42,9 +42,6 @@ $forms['Servers']['Server_auth'] = array('Servers' => array(1 => array(
'user',
'password',
':group:end',
':group:' . __('Cookie authentication'),
'auth_swekey_config' => './swekey.conf',
':group:end',
':group:' . __('HTTP authentication'),
'auth_http_realm',
':group:end',
@ -183,7 +180,6 @@ $forms['Main_panel']['Startup'] = array(
'ShowCreateDb',
'ShowStats',
'ShowServerInfo',
'ShowPhpInfo',
'ShowChgPassword');
$forms['Main_panel']['DbStructure'] = array(
'ShowDbStructureCreation',

View File

@ -15,6 +15,8 @@
* @package PhpMyAdmin
*/
require_once './libraries/Util.class.php';
/**
* Returns validator list
*
@ -275,6 +277,11 @@ function validate_server($path, $values)
'Servers/1/SignonURL' => ''
);
$error = false;
if (empty($values['Servers/1/auth_type'])) {
$values['Servers/1/auth_type'] = '';
$result['Servers/1/auth_type'] = __('Invalid authentication type!');
$error = true;
}
if ($values['Servers/1/auth_type'] == 'config'
&& empty($values['Servers/1/user'])
) {
@ -300,15 +307,15 @@ function validate_server($path, $values)
}
if (!$error && $values['Servers/1/auth_type'] == 'config') {
$password = $values['Servers/1/nopassword'] ? null
: $values['Servers/1/password'];
$password = !empty($values['Servers/1/nopassword']) && $values['Servers/1/nopassword'] ? null
: (empty($values['Servers/1/password']) ? '' : $values['Servers/1/password']);
$test = test_db_connection(
$values['Servers/1/extension'],
$values['Servers/1/connect_type'],
$values['Servers/1/host'],
$values['Servers/1/port'],
$values['Servers/1/socket'],
$values['Servers/1/user'],
empty($values['Servers/1/extension']) ? '' : $values['Servers/1/extension'],
empty($values['Servers/1/connect_type']) ? '' : $values['Servers/1/connect_type'],
empty($values['Servers/1/host']) ? '' : PMA_sanitizeMySQLHost($values['Servers/1/host']),
empty($values['Servers/1/port']) ? '' : $values['Servers/1/port'],
empty($values['Servers/1/socket']) ? '' : $values['Servers/1/socket'],
empty($values['Servers/1/user']) ? '' : $values['Servers/1/user'],
$password,
'Server'
);
@ -336,17 +343,17 @@ function validate_pmadb($path, $values)
);
$error = false;
if ($values['Servers/1/pmadb'] == '') {
if (empty($values['Servers/1/pmadb'])) {
return $result;
}
$result = array();
if ($values['Servers/1/controluser'] == '') {
if (empty($values['Servers/1/controluser'])) {
$result['Servers/1/controluser']
= __('Empty phpMyAdmin control user while using pmadb');
$error = true;
}
if ($values['Servers/1/controlpass'] == '') {
if (empty($values['Servers/1/controlpass'])) {
$result['Servers/1/controlpass']
= __('Empty phpMyAdmin control user password while using pmadb');
$error = true;
@ -354,7 +361,7 @@ function validate_pmadb($path, $values)
if (!$error) {
$test = test_db_connection(
$values['Servers/1/extension'], $values['Servers/1/connect_type'],
$values['Servers/1/host'], $values['Servers/1/port'],
$values['Servers/1/host'], PMA_sanitizeMySQLHost($values['Servers/1/port']),
$values['Servers/1/socket'], $values['Servers/1/controluser'],
$values['Servers/1/controlpass'], 'Server_pmadb'
);
@ -378,7 +385,7 @@ function validate_regex($path, $values)
{
$result = array($path => '');
if ($values[$path] == '') {
if (empty($values[$path])) {
return $result;
}
@ -415,10 +422,11 @@ function validate_trusted_proxies($path, $values)
return $result;
}
if (is_array($values[$path])) {
if (is_array($values[$path]) || is_object($values[$path])) {
// value already processed by FormDisplay::save
$lines = array();
foreach ($values[$path] as $ip => $v) {
$v = PMA_Util::requestString($v);
$lines[] = preg_match('/^-\d+$/', $ip)
? $v
: $ip . ': ' . $v;
@ -469,7 +477,7 @@ function test_number(
$max_value,
$error_string
) {
if ($values[$path] === '') {
if (empty($values[$path])) {
return '';
}
@ -562,7 +570,11 @@ function validate_non_negative_number($path, $values)
*/
function validate_by_regex($path, $values, $regex)
{
$result = preg_match($regex, $values[$path]);
if (empty($values[$path])) {
return '';
}
$result = preg_match($regex, PMA_Util::requestString($values[$path]));
return array($path => ($result ? '' : __('Incorrect value')));
}

View File

@ -552,7 +552,7 @@ function PMA_sendHeaderLocation($uri, $use_refresh = false)
echo '<body>' . "\n";
echo '<script type="text/javascript">' . "\n";
echo '//<![CDATA[' . "\n";
echo 'document.write(\'<p><a href="' . htmlspecialchars($uri) . '">'
echo 'document.write(\'<p><a href="' . PMA_escapeJsString(htmlspecialchars($uri)) . '">'
. __('Go') . '</a></p>\');' . "\n";
echo '//]]>' . "\n";
echo '</script></body></html>' . "\n";
@ -568,11 +568,6 @@ function PMA_sendHeaderLocation($uri, $use_refresh = false)
} else {
session_write_close();
if (headers_sent()) {
if (function_exists('debug_print_backtrace')) {
echo '<pre>';
debug_print_backtrace();
echo '</pre>';
}
trigger_error(
'PMA_sendHeaderLocation called when headers are already sent!',
E_USER_ERROR
@ -755,7 +750,7 @@ function PMA_arrayRemove($path, &$array)
*/
function PMA_linkURL($url)
{
if (!preg_match('#^https?://#', $url) || defined('PMA_SETUP')) {
if (!preg_match('#^https?://#', $url)) {
return $url;
} else {
if (!function_exists('PMA_generate_common_url')) {
@ -763,8 +758,12 @@ function PMA_linkURL($url)
}
$params = array();
$params['url'] = $url;
if (defined('PMA_SETUP')) {
return '../url.php' . PMA_generate_common_url($params);
} else {
return './url.php' . PMA_generate_common_url($params);
}
}
}
/**
@ -799,4 +798,217 @@ function PMA_addJSVar($key, $value, $escape = true)
PMA_addJSCode(PMA_getJsValue($key, $value, $escape));
}
/* Compatibility with PHP < 5.6 */
if(! function_exists('hash_equals')) {
function hash_equals($a, $b) {
$ret = strlen($a) ^ strlen($b);
$ret |= array_sum(unpack("C*", $a ^ $b));
return ! $ret;
}
}
/**
* Checks whether domain of URL is whitelisted domain or not.
* Use only for URLs of external sites.
*
* @param string $url URL of external site.
*
* @return boolean.True:if domain of $url is allowed domain, False:otherwise.
*/
function PMA_isAllowedDomain($url)
{
$arr = parse_url($url);
// We need host to be set
if (! isset($arr['host']) || strlen($arr['host']) == 0) {
return false;
}
// We do not want these to be present
$blocked = array('user', 'pass', 'port');
foreach ($blocked as $part) {
if (isset($arr[$part]) && strlen($arr[$part]) != 0) {
return false;
}
}
$domain = $arr["host"];
$domainWhiteList = array(
/* Include current domain */
$_SERVER['SERVER_NAME'],
/* phpMyAdmin domains */
'wiki.phpmyadmin.net', 'www.phpmyadmin.net', 'phpmyadmin.net',
'docs.phpmyadmin.net',
'demo.phpmyadmin.net',
/* mysql.com domains */
'dev.mysql.com','bugs.mysql.com',
/* mariadb domains */
'mariadb.org', 'mariadb.com',
/* php.net domains */
'php.net',
/* sourceforge.net domain */
'sourceforge.net',
/* Github domains*/
'github.com','www.github.com',
/* Percona domains */
'www.percona.com',
/* Following are doubtful ones. */
'www.primebase.com','pbxt.blogspot.com',
'mysqldatabaseadministration.blogspot.com',
/* CVE */
'cve.mitre.org',
);
if (in_array($domain, $domainWhiteList)) {
return true;
}
return false;
}
/* Compatibility with PHP < 5.1 or PHP without hash extension */
if (! function_exists('hash_hmac')) {
function hash_hmac($algo, $data, $key, $raw_output = false)
{
$algo = strtolower($algo);
$pack = 'H'.strlen($algo('test'));
$size = 64;
$opad = str_repeat(chr(0x5C), $size);
$ipad = str_repeat(chr(0x36), $size);
if (strlen($key) > $size) {
$key = str_pad(pack($pack, $algo($key)), $size, chr(0x00));
} else {
$key = str_pad($key, $size, chr(0x00));
}
for ($i = 0; $i < strlen($key) - 1; $i++) {
$opad[$i] = $opad[$i] ^ $key[$i];
$ipad[$i] = $ipad[$i] ^ $key[$i];
}
$output = $algo($opad.pack($pack, $algo($ipad.$data)));
return ($raw_output) ? pack($pack, $output) : $output;
}
}
/**
* Sanitizes MySQL hostname
*
* * strips p: prefix(es)
*
* @param string $name User given hostname
*
* @return string
*/
function PMA_sanitizeMySQLHost($name)
{
while (strtolower(substr($name, 0, 2)) == 'p:') {
$name = substr($name, 2);
}
return $name;
}
/**
* Sanitizes MySQL username
*
* * strips part behind null byte
*
* @param string $name User given username
*
* @return string
*/
function PMA_sanitizeMySQLUser($name)
{
$position = strpos($name, chr(0));
if ($position !== false) {
return substr($name, 0, $position);
}
return $name;
}
/**
* Safe unserializer wrapper
*
* It does not unserialize data containing objects
*
* @param string $data Data to unserialize
*
* @return mixed
*/
function PMA_safeUnserialize($data)
{
if (! is_string($data)) {
return null;
}
/* validate serialized data */
$length = strlen($data);
$depth = 0;
for ($i = 0; $i < $length; $i++) {
$value = $data[$i];
switch ($value)
{
case '}':
/* end of array */
if ($depth <= 0) {
return null;
}
$depth--;
break;
case 's':
/* string */
// parse sting length
$strlen = intval(substr($data, $i + 2));
// string start
$i = strpos($data, ':', $i + 2);
if ($i === false) {
return null;
}
// skip string, quotes and ;
$i += 2 + $strlen + 1;
if ($data[$i] != ';') {
return null;
}
break;
case 'b':
case 'i':
case 'd':
/* bool, integer or double */
// skip value to sepearator
$i = strpos($data, ';', $i);
if ($i === false) {
return null;
}
break;
case 'a':
/* array */
// find array start
$i = strpos($data, '{', $i);
if ($i === false) {
return null;
}
// remember nesting
$depth++;
break;
case 'N':
/* null */
// skip to end
$i = strpos($data, ';', $i);
if ($i === false) {
return null;
}
break;
default:
/* any other elements are not wanted */
return null;
}
}
// check unterminated arrays
if ($depth > 0) {
return null;
}
return unserialize($data);
}
?>

View File

@ -139,11 +139,11 @@ function PMA_DBI_DBG_query($query, $link, $result, $time)
} else {
$_SESSION['debug']['queries'][$hash] = array();
if ($result == false) {
$_SESSION['debug']['queries'][$hash]['error']
= '<b style="color:red">' . mysqli_error($link) . '</b>';
$_SESSION['debug']['queries'][$hash]['error'] = '<b style="color:red">'
. htmlspecialchars(mysqli_error($link)) . '</b>';
}
$_SESSION['debug']['queries'][$hash]['count'] = 1;
$_SESSION['debug']['queries'][$hash]['query'] = $query;
$_SESSION['debug']['queries'][$hash]['query'] = htmlspecialchars($query);
$_SESSION['debug']['queries'][$hash]['time'] = $time;
}
@ -1567,11 +1567,22 @@ function PMA_DBI_postConnect($link, $is_controluser = false)
PMA_DBI_query("SET CHARACTER SET 'utf8';", $link, PMA_DBI_QUERY_STORE);
$set_collation_con_query = "SET collation_connection = '"
. PMA_Util::sqlAddSlashes($GLOBALS['collation_connection']) . "';";
PMA_DBI_query(
$result = PMA_DBI_try_query(
$set_collation_con_query,
$link,
PMA_DBI_QUERY_STORE
);
if ($result === false) {
trigger_error(
__('Failed to set configured collation connection!'),
E_USER_WARNING
);
$result = PMA_DBI_query(
"SET collation_connection = 'utf8_general_ci'",
$link,
PMA_DBI_QUERY_STORE
);
}
} else {
PMA_DBI_query(
"SET NAMES 'utf8' COLLATE 'utf8_general_ci';",

View File

@ -258,6 +258,18 @@ $GLOBALS['dummy_queries'] = array(
'query' => 'SHOW TABLES FROM `pma`;',
'result' => array(),
),
array(
'query' => 'SHOW TABLES FROM `mysql`;',
'result' => array(),
),
array(
'query' => "SELECT `PRIVILEGE_TYPE` FROM `INFORMATION_SCHEMA`.`SCHEMA_PRIVILEGES` WHERE GRANTEE='''pma_test''@''localhost''' AND PRIVILEGE_TYPE='TRIGGER' AND 'mysql' REGEXP REPLACE(REPLACE(TABLE_SCHEMA, '_', '.'), '%', '.*')",
'result' => array(),
),
array(
'query' => "SELECT `PRIVILEGE_TYPE` FROM `INFORMATION_SCHEMA`.`SCHEMA_PRIVILEGES` WHERE GRANTEE='''pma_test''@''localhost''' AND PRIVILEGE_TYPE='EVENT' AND 'mysql' REGEXP REPLACE(REPLACE(TABLE_SCHEMA, '_', '.'), '%', '.*')",
'result' => array(),
),
array(
'query' => "SELECT `PRIVILEGE_TYPE` FROM `INFORMATION_SCHEMA`.`SCHEMA_PRIVILEGES` WHERE GRANTEE='''pma_test''@''localhost''' AND PRIVILEGE_TYPE='EVENT' AND TABLE_SCHEMA='pma'",
'result' => array(),

View File

@ -114,10 +114,12 @@ function PMA_DBI_connect(
$client_flags = 0;
// always use CLIENT_LOCAL_FILES as defined in mysql_com.h
if (defined('PMA_ENABLE_LDI')) {
// use CLIENT_LOCAL_FILES as defined in mysql_com.h
// for the case where the client library was not compiled
// with --enable-local-infile
$client_flags |= 128;
}
/* Optionally compress connection */
if (defined('MYSQL_CLIENT_COMPRESS') && $cfg['Server']['compress']) {

View File

@ -147,7 +147,11 @@ function PMA_DBI_connect(
$link = mysqli_init();
if (defined('PMA_ENABLE_LDI')) {
mysqli_options($link, MYSQLI_OPT_LOCAL_INFILE, true);
} else {
mysqli_options($link, MYSQLI_OPT_LOCAL_INFILE, false);
}
$client_flags = 0;

View File

@ -25,7 +25,7 @@ if ($is_create_db_priv) {
. PMA_Util::showMySQLDocu('SQL-Syntax', 'CREATE_DATABASE'); ?></strong><br />
<?php echo PMA_generate_common_hidden_inputs('', '', 5); ?>
<input type="hidden" name="reload" value="1" />
<input type="text" name="new_db" value="<?php echo $db_to_create; ?>" maxlength="64" class="textfield" id="text_create_db"/>
<input type="text" name="new_db" value="<?php echo htmlspecialchars($db_to_create); ?>" maxlength="64" class="textfield" id="text_create_db"/>
<?php
include_once './libraries/mysql_charsets.lib.php';
echo PMA_generateCharsetDropdownBox(PMA_CSDROPDOWN_COLLATION, 'db_collation', null, null, true, 5);

View File

@ -40,7 +40,7 @@ function PMA_printGitRevision()
'https://github.com/phpmyadmin/phpmyadmin/commit/'
. $GLOBALS['PMA_Config']->get('PMA_VERSION_GIT_COMMITHASH')
)
. '" target="_blank">' . $commit_hash . '</a>';
. '" rel="noopener noreferrer" target="_blank">' . $commit_hash . '</a>';
}
$branch = $GLOBALS['PMA_Config']->get('PMA_VERSION_GIT_BRANCH');
@ -50,7 +50,7 @@ function PMA_printGitRevision()
'https://github.com/phpmyadmin/phpmyadmin/tree/'
. $GLOBALS['PMA_Config']->get('PMA_VERSION_GIT_BRANCH')
)
. '" target="_blank">' . $branch . '</a>';
. '" rel="noopener noreferrer" target="_blank">' . $branch . '</a>';
}
if ($branch !== false) {
$branch = sprintf(__('%1$s from %2$s branch'), $commit_hash, $branch);

View File

@ -132,11 +132,11 @@ class PMA_StorageEngine_pbxt extends PMA_StorageEngine
function getPageDocumentation()
{
$output = '<p>'
. sprintf(__('Documentation and further information about PBXT can be found on the %sPrimeBase XT Home Page%s.'), '<a href="' . PMA_linkURL('http://www.primebase.com/xt/') . '" target="_blank">', '</a>')
. sprintf(__('Documentation and further information about PBXT can be found on the %sPrimeBase XT Home Page%s.'), '<a href="' . PMA_linkURL('http://www.primebase.com/xt/') . '" rel="noopener noreferrer" target="_blank">', '</a>')
. '</p>' . "\n"
. '<h3>' . __('Related Links') . '</h3>' . "\n"
. '<ul>' . "\n"
. '<li><a href="' . PMA_linkURL('http://pbxt.blogspot.com/') . '" target="_blank">' . __('The PrimeBase XT Blog by Paul McCullagh') . '</a></li>' . "\n"
. '<li><a href="' . PMA_linkURL('http://pbxt.blogspot.com/') . '" rel="noopener noreferrer" target="_blank">' . __('The PrimeBase XT Blog by Paul McCullagh') . '</a></li>' . "\n"
. '</ul>' . "\n";
return $output;

View File

@ -30,6 +30,7 @@ function PMA_getDirContent($dir, $expression = '')
if ('.' != $file
&& '..' != $file
&& is_file($dir . $file)
&& ! is_link($dir . $file)
&& ($expression == '' || preg_match($expression, $file))
) {
$result[] = $file;

View File

@ -31,7 +31,9 @@ class PMA_GIS_Factory
include_once './libraries/gis/pma_gis_geometry.php';
$type_lower = strtolower($type);
if (! file_exists('./libraries/gis/pma_gis_' . $type_lower . '.php')) {
if (! PMA_isValid($type_lower, PMA_Util::getGISDatatypes())
|| ! file_exists('./libraries/gis/pma_gis_' . $type_lower . '.php')
) {
return false;
}
if (include_once './libraries/gis/pma_gis_' . $type_lower . '.php') {

View File

@ -117,11 +117,11 @@ abstract class PMA_GIS_Geometry
. 'bound.extend(new OpenLayers.LonLat('
. $scale_data['minX'] . ', ' . $scale_data['minY']
. ').transform(new OpenLayers.Projection("EPSG:'
. $srid . '"), map.getProjectionObject())); '
. intval($srid) . '"), map.getProjectionObject())); '
. 'bound.extend(new OpenLayers.LonLat('
. $scale_data['maxX'] . ', ' . $scale_data['maxY']
. ').transform(new OpenLayers.Projection("EPSG:'
. $srid . '"), map.getProjectionObject()));';
. intval($srid) . '"), map.getProjectionObject()));';
}
/**
@ -215,8 +215,8 @@ abstract class PMA_GIS_Geometry
$y = $scale_data['height']
- ($cordinates[1] - $scale_data['y']) * $scale_data['scale'];
} else {
$x = trim($cordinates[0]);
$y = trim($cordinates[1]);
$x = floatval(trim($cordinates[0]));
$y = floatval(trim($cordinates[1]));
}
} else {
$x = '';
@ -355,7 +355,7 @@ abstract class PMA_GIS_Geometry
{
return '(new OpenLayers.Geometry.Point(' . $point[0] . ',' . $point[1] . '))'
. '.transform(new OpenLayers.Projection("EPSG:'
. $srid . '"), map.getProjectionObject())';
. intval($srid) . '"), map.getProjectionObject())';
}
}
?>

View File

@ -802,7 +802,7 @@ function PMA_detectType($last_cumulative_type, $cell)
* @return array array(array $types, array $sizes)
* @access public
*
* @link http://wiki.phpmyadmin.net/pma/Import
* @link https://wiki.phpmyadmin.net/pma/Import
*
* @todo Handle the error case more elegantly
*/
@ -911,7 +911,7 @@ $import_notice = null;
* @return void
* @access public
*
* @link http://wiki.phpmyadmin.net/pma/Import
* @link https://wiki.phpmyadmin.net/pma/Import
*/
function PMA_buildSQL($db_name, &$tables, &$analyses = null,
&$additional_sql = null, $options = null

View File

@ -29,19 +29,29 @@ function PMA_getIp()
/* Do we trust this IP as a proxy? If yes we will use it's header. */
if (isset($GLOBALS['cfg']['TrustedProxies'][$direct_ip])) {
$trusted_header_value
= PMA_getenv($GLOBALS['cfg']['TrustedProxies'][$direct_ip]);
$matches = array();
/**
* Parse header in form:
* X-Forwarded-For: client, proxy1, proxy2
*/
// Get header content
$value = PMA_getenv($GLOBALS['cfg']['TrustedProxies'][$direct_ip]);
// Grab first element what is client adddress
$values = explode(',', $value);
$value = $values[0];
// Extract IP address
// the $ checks that the header contains only one IP address,
// ?: makes sure the () don't capture
$matches = array();
$is_ip = preg_match(
'|^(?:[0-9]{1,3}\.){3,3}[0-9]{1,3}$|',
$trusted_header_value, $matches
$value, $matches
);
if ($is_ip && (count($matches) == 1)) {
// True IP behind a proxy
return $matches[0];
}
// We could not parse header
return false;
}
/* Return true IP */
@ -182,7 +192,7 @@ function PMA_ipv6MaskTest($test_range, $ip_to_test)
if ($is_single) {
$range_hex = bin2hex(inet_pton($test_range));
$result = $ip_hex === $range_hex;
$result = hash_equals($ip_hex, $range_hex);
} elseif ($is_range) {
// what range do we operate on?
$range_match = array();
@ -296,7 +306,7 @@ function PMA_allowDeny($type)
// check for username
if (($rule_data[1] != '%') //wildcarded first
&& ($rule_data[1] != $username)
&& (! hash_equals($rule_data[1], $username))
) {
continue;
}

View File

@ -170,12 +170,14 @@ if (!empty($submit_mult) && !empty($what)) {
foreach ($selected AS $idx => $sval) {
switch ($what) {
case 'row_delete':
$full_query .= 'DELETE FROM ' . PMA_Util::backquote($db) . '.' . PMA_Util::backquote($table)
$full_query .= 'DELETE FROM '
. PMA_Util::backquote(htmlspecialchars($db))
. '.' . PMA_Util::backquote(htmlspecialchars($table))
// Do not append a "LIMIT 1" clause here
// (it's not binlog friendly).
// We don't need the clause because the calling panel permits
// this feature only when there is a unique index.
. ' WHERE ' . urldecode($sval)
. ' WHERE ' . htmlspecialchars(urldecode($sval))
. ';<br />';
break;
case 'drop_db':

View File

@ -82,10 +82,9 @@ class PMA_NavigationHeader
$retval .= '<div id="pmalogo">';
if ($GLOBALS['cfg']['NavigationLogoLink']) {
$logo_link = trim(htmlspecialchars($GLOBALS['cfg']['NavigationLogoLink']));
// prevent XSS, see PMASA-2013-9
// if link has protocol, allow only http and https
if (preg_match('/^[a-z]+:/i', $logo_link)
&& ! preg_match('/^https?:/i', $logo_link)) {
$parsed = parse_url($logo_link);
/* Allow only links with http/https */
if (! isset($parsed['scheme']) || ! in_array(strtolower($parsed['scheme']), array('http', 'https'))) {
$logo_link = 'index.php';
}
$retval .= ' <a href="' . $logo_link;

View File

@ -283,7 +283,7 @@ class Node
$retval = true;
} else {
foreach ($this->parent->children as $child) {
if ($child != $this
if ($child !== $this
&& ($child->type == Node::OBJECT || $child->hasChildren(false))
) {
$retval = true;

View File

@ -350,6 +350,10 @@ class gettext_reader {
* @return int array index of the right plural form
*/
function select_string($n) {
if (!is_int($n)) {
throw new InvalidArgumentException(
"Select_string only accepts integers: " . $n);
}
$string = $this->get_plural_forms();
$string = str_replace('nplurals',"\$total",$string);
$string = str_replace("n",$n,$string);

View File

@ -0,0 +1,299 @@
<?php
/**
* Random Number Generator
*
* The idea behind this function is that it can be easily replaced with your own crypt_random_string()
* function. eg. maybe you have a better source of entropy for creating the initial states or whatever.
*
* PHP versions 4 and 5
*
* Here's a short example of how to use this library:
* <code>
* <?php
* include 'Crypt/Random.php';
*
* echo bin2hex(crypt_random_string(8));
* ?>
* </code>
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Crypt
* @package Crypt_Random
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2007 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
// laravel is a PHP framework that utilizes phpseclib. laravel workbenches may, independently,
// have phpseclib as a requirement as well. if you're developing such a program you may encounter
// a "Cannot redeclare crypt_random_string()" error.
if (!function_exists('crypt_random_string')) {
/**
* "Is Windows" test
*
* @access private
*/
define('CRYPT_RANDOM_IS_WINDOWS', strtoupper(substr(PHP_OS, 0, 3)) === 'WIN');
/**
* Generate a random string.
*
* Although microoptimizations are generally discouraged as they impair readability this function is ripe with
* microoptimizations because this function has the potential of being called a huge number of times.
* eg. for RSA key generation.
*
* @param int $length
* @return string
* @access public
*/
function crypt_random_string($length)
{
if (CRYPT_RANDOM_IS_WINDOWS) {
// method 1. prior to PHP 5.3, mcrypt_create_iv() would call rand() on windows
if (extension_loaded('mcrypt') && version_compare(PHP_VERSION, '5.3.0', '>=')) {
return mcrypt_create_iv($length);
}
// method 2. openssl_random_pseudo_bytes was introduced in PHP 5.3.0 but prior to PHP 5.3.4 there was,
// to quote <http://php.net/ChangeLog-5.php#5.3.4>, "possible blocking behavior". as of 5.3.4
// openssl_random_pseudo_bytes and mcrypt_create_iv do the exact same thing on Windows. ie. they both
// call php_win32_get_random_bytes():
//
// https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/openssl/openssl.c#L5008
// https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/mcrypt/mcrypt.c#L1392
//
// php_win32_get_random_bytes() is defined thusly:
//
// https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/win32/winutil.c#L80
//
// we're calling it, all the same, in the off chance that the mcrypt extension is not available
if (extension_loaded('openssl') && version_compare(PHP_VERSION, '5.3.4', '>=')) {
return openssl_random_pseudo_bytes($length);
}
} else {
// method 1. the fastest
if (extension_loaded('openssl') && version_compare(PHP_VERSION, '5.3.0', '>=')) {
return openssl_random_pseudo_bytes($length);
}
// method 2
static $fp = true;
if ($fp === true) {
// warning's will be output unles the error suppression operator is used. errors such as
// "open_basedir restriction in effect", "Permission denied", "No such file or directory", etc.
$fp = @fopen('/dev/urandom', 'rb');
}
if ($fp !== true && $fp !== false) { // surprisingly faster than !is_bool() or is_resource()
return fread($fp, $length);
}
// method 3. pretty much does the same thing as method 2 per the following url:
// https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/mcrypt/mcrypt.c#L1391
// surprisingly slower than method 2. maybe that's because mcrypt_create_iv does a bunch of error checking that we're
// not doing. regardless, this'll only be called if this PHP script couldn't open /dev/urandom due to open_basedir
// restrictions or some such
if (extension_loaded('mcrypt')) {
return mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
}
}
// at this point we have no choice but to use a pure-PHP CSPRNG
// cascade entropy across multiple PHP instances by fixing the session and collecting all
// environmental variables, including the previous session data and the current session
// data.
//
// mt_rand seeds itself by looking at the PID and the time, both of which are (relatively)
// easy to guess at. linux uses mouse clicks, keyboard timings, etc, as entropy sources, but
// PHP isn't low level to be able to use those as sources and on a web server there's not likely
// going to be a ton of keyboard or mouse action. web servers do have one thing that we can use
// however, a ton of people visiting the website. obviously you don't want to base your seeding
// soley on parameters a potential attacker sends but (1) not everything in $_SERVER is controlled
// by the user and (2) this isn't just looking at the data sent by the current user - it's based
// on the data sent by all users. one user requests the page and a hash of their info is saved.
// another user visits the page and the serialization of their data is utilized along with the
// server envirnment stuff and a hash of the previous http request data (which itself utilizes
// a hash of the session data before that). certainly an attacker should be assumed to have
// full control over his own http requests. he, however, is not going to have control over
// everyone's http requests.
static $crypto = false, $v;
if ($crypto === false) {
// save old session data
$old_session_id = session_id();
$old_use_cookies = ini_get('session.use_cookies');
$old_session_cache_limiter = session_cache_limiter();
$_OLD_SESSION = isset($_SESSION) ? $_SESSION : false;
if ($old_session_id != '') {
session_write_close();
}
session_id(1);
ini_set('session.use_cookies', 0);
session_cache_limiter('');
session_start();
$v = $seed = $_SESSION['seed'] = pack('H*', sha1(
serialize($_SERVER) .
serialize($_POST) .
serialize($_GET) .
serialize($_COOKIE) .
serialize($GLOBALS) .
serialize($_SESSION) .
serialize($_OLD_SESSION)
));
if (!isset($_SESSION['count'])) {
$_SESSION['count'] = 0;
}
$_SESSION['count']++;
session_write_close();
// restore old session data
if ($old_session_id != '') {
session_id($old_session_id);
session_start();
ini_set('session.use_cookies', $old_use_cookies);
session_cache_limiter($old_session_cache_limiter);
} else {
if ($_OLD_SESSION !== false) {
$_SESSION = $_OLD_SESSION;
unset($_OLD_SESSION);
} else {
unset($_SESSION);
}
}
// in SSH2 a shared secret and an exchange hash are generated through the key exchange process.
// the IV client to server is the hash of that "nonce" with the letter A and for the encryption key it's the letter C.
// if the hash doesn't produce enough a key or an IV that's long enough concat successive hashes of the
// original hash and the current hash. we'll be emulating that. for more info see the following URL:
//
// http://tools.ietf.org/html/rfc4253#section-7.2
//
// see the is_string($crypto) part for an example of how to expand the keys
$key = pack('H*', sha1($seed . 'A'));
$iv = pack('H*', sha1($seed . 'C'));
// ciphers are used as per the nist.gov link below. also, see this link:
//
// http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator#Designs_based_on_cryptographic_primitives
switch (true) {
case phpseclib_resolve_include_path('Crypt/AES.php'):
if (!class_exists('Crypt_AES')) {
include_once 'AES.php';
}
$crypto = new Crypt_AES(CRYPT_AES_MODE_CTR);
break;
case phpseclib_resolve_include_path('Crypt/Twofish.php'):
if (!class_exists('Crypt_Twofish')) {
include_once 'Twofish.php';
}
$crypto = new Crypt_Twofish(CRYPT_TWOFISH_MODE_CTR);
break;
case phpseclib_resolve_include_path('Crypt/Blowfish.php'):
if (!class_exists('Crypt_Blowfish')) {
include_once 'Blowfish.php';
}
$crypto = new Crypt_Blowfish(CRYPT_BLOWFISH_MODE_CTR);
break;
case phpseclib_resolve_include_path('Crypt/TripleDES.php'):
if (!class_exists('Crypt_TripleDES')) {
include_once 'TripleDES.php';
}
$crypto = new Crypt_TripleDES(CRYPT_DES_MODE_CTR);
break;
case phpseclib_resolve_include_path('Crypt/DES.php'):
if (!class_exists('Crypt_DES')) {
include_once 'DES.php';
}
$crypto = new Crypt_DES(CRYPT_DES_MODE_CTR);
break;
case phpseclib_resolve_include_path('Crypt/RC4.php'):
if (!class_exists('Crypt_RC4')) {
include_once 'RC4.php';
}
$crypto = new Crypt_RC4();
break;
default:
user_error('crypt_random_string requires at least one symmetric cipher be loaded');
return false;
}
$crypto->setKey($key);
$crypto->setIV($iv);
$crypto->enableContinuousBuffer();
}
//return $crypto->encrypt(str_repeat("\0", $length));
// the following is based off of ANSI X9.31:
//
// http://csrc.nist.gov/groups/STM/cavp/documents/rng/931rngext.pdf
//
// OpenSSL uses that same standard for it's random numbers:
//
// http://www.opensource.apple.com/source/OpenSSL/OpenSSL-38/openssl/fips-1.0/rand/fips_rand.c
// (do a search for "ANS X9.31 A.2.4")
$result = '';
while (strlen($result) < $length) {
$i = $crypto->encrypt(microtime()); // strlen(microtime()) == 21
$r = $crypto->encrypt($i ^ $v); // strlen($v) == 20
$v = $crypto->encrypt($r ^ $i); // strlen($r) == 20
$result.= $r;
}
return substr($result, 0, $length);
}
}
if (!function_exists('phpseclib_resolve_include_path')) {
/**
* Resolve filename against the include path.
*
* Wrapper around stream_resolve_include_path() (which was introduced in
* PHP 5.3.2) with fallback implementation for earlier PHP versions.
*
* @param string $filename
* @return string|false
* @access public
*/
function phpseclib_resolve_include_path($filename)
{
if (function_exists('stream_resolve_include_path')) {
return stream_resolve_include_path($filename);
}
// handle non-relative paths
if (file_exists($filename)) {
return realpath($filename);
}
$paths = PATH_SEPARATOR == ':' ?
preg_split('#(?<!phar):#', get_include_path()) :
explode(PATH_SEPARATOR, get_include_path());
foreach ($paths as $prefix) {
// path's specified in include_path don't always end in /
$ds = substr($prefix, -1) == DIRECTORY_SEPARATOR ? '' : DIRECTORY_SEPARATOR;
$file = $prefix . $ds . $filename;
if (file_exists($file)) {
return realpath($file);
}
}
return false;
}
}

View File

@ -31,8 +31,10 @@ function PMA_getPlugin(
$file = $class_name . ".class.php";
if (is_file($plugins_dir . $file)) {
include_once $plugins_dir . $file;
if (class_exists($class_name)) {
return new $class_name;
}
}
return null;
}

View File

@ -41,6 +41,15 @@ abstract class AuthenticationPlugin extends PluginObserver
*/
abstract public function authSetUser();
/**
* Stores user credentials after successful login.
*
* @return void
*/
public function storeUserCredentials()
{
}
/**
* User is not allowed to login to MySQL -> authentication failed
*

View File

@ -23,11 +23,6 @@ if (! empty($_REQUEST['target'])) {
$GLOBALS['target'] = basename(PMA_getenv('SCRIPT_NAME'));
}
/**
* Swekey authentication functions.
*/
require './libraries/plugins/auth/swekey/swekey.auth.lib.php';
/**
* Initialization
* Store the initialization vector because it will be needed for
@ -143,7 +138,7 @@ class AuthenticationCookie extends AuthenticationPlugin
echo '
<div class="container">
<a href="';
echo PMA_linkURL('http://www.phpmyadmin.net/');
echo PMA_linkURL('https://www.phpmyadmin.net/');
echo '" target="_blank" class="logo">';
$logo_image = $GLOBALS['pmaThemeImage'] . 'logo_right.png';
if (@file_exists($logo_image)) {
@ -258,10 +253,6 @@ class AuthenticationCookie extends AuthenticationPlugin
echo '</fieldset>
</form>';
// BEGIN Swekey Integration
Swekey_login('input_username', 'input_go');
// END Swekey Integration
if ($GLOBALS['error_handler']->hasDisplayErrors()) {
echo '<div>';
$GLOBALS['error_handler']->dispErrors();
@ -306,16 +297,9 @@ class AuthenticationCookie extends AuthenticationPlugin
$GLOBALS['PHP_AUTH_USER'] = $GLOBALS['PHP_AUTH_PW'] = '';
$GLOBALS['from_cookie'] = false;
// BEGIN Swekey Integration
if (! Swekey_auth_check()) {
return false;
}
// END Swekey Integration
if (defined('PMA_CLEAR_COOKIES')) {
foreach ($GLOBALS['cfg']['Servers'] as $key => $val) {
$GLOBALS['PMA_Config']->removeCookie('pmaPass-' . $key);
$GLOBALS['PMA_Config']->removeCookie('pmaServer-' . $key);
$GLOBALS['PMA_Config']->removeCookie('pmaAuth-' . $key);
$GLOBALS['PMA_Config']->removeCookie('pmaUser-' . $key);
}
return false;
@ -332,31 +316,31 @@ class AuthenticationCookie extends AuthenticationPlugin
// -> delete password cookie(s)
if ($GLOBALS['cfg']['LoginCookieDeleteAll']) {
foreach ($GLOBALS['cfg']['Servers'] as $key => $val) {
$GLOBALS['PMA_Config']->removeCookie('pmaPass-' . $key);
if (isset($_COOKIE['pmaPass-' . $key])) {
unset($_COOKIE['pmaPass-' . $key]);
$GLOBALS['PMA_Config']->removeCookie('pmaAuth-' . $key);
if (isset($_COOKIE['pmaAuth-' . $key])) {
unset($_COOKIE['pmaAuth-' . $key]);
}
}
} else {
$GLOBALS['PMA_Config']->removeCookie(
'pmaPass-' . $GLOBALS['server']
'pmaAuth-' . $GLOBALS['server']
);
if (isset($_COOKIE['pmaPass-' . $GLOBALS['server']])) {
unset($_COOKIE['pmaPass-' . $GLOBALS['server']]);
if (isset($_COOKIE['pmaAuth-' . $GLOBALS['server']])) {
unset($_COOKIE['pmaAuth-' . $GLOBALS['server']]);
}
}
}
if (! empty($_REQUEST['pma_username'])) {
// The user just logged in
$GLOBALS['PHP_AUTH_USER'] = $_REQUEST['pma_username'];
$GLOBALS['PHP_AUTH_USER'] = PMA_sanitizeMySQLUser($_REQUEST['pma_username']);
$GLOBALS['PHP_AUTH_PW'] = empty($_REQUEST['pma_password'])
? ''
: $_REQUEST['pma_password'];
if ($GLOBALS['cfg']['AllowArbitraryServer']
&& isset($_REQUEST['pma_servername'])
) {
$GLOBALS['pma_auth_server'] = $_REQUEST['pma_servername'];
$GLOBALS['pma_auth_server'] = PMA_sanitizeMySQLHost($_REQUEST['pma_servername']);
}
return true;
}
@ -364,22 +348,14 @@ class AuthenticationCookie extends AuthenticationPlugin
// At the end, try to set the $GLOBALS['PHP_AUTH_USER']
// and $GLOBALS['PHP_AUTH_PW'] variables from cookies
// servername
if ($GLOBALS['cfg']['AllowArbitraryServer']
&& ! empty($_COOKIE['pmaServer-' . $GLOBALS['server']])
) {
$GLOBALS['pma_auth_server']
= $_COOKIE['pmaServer-' . $GLOBALS['server']];
}
// username
// check cookies
if (empty($_COOKIE['pmaUser-' . $GLOBALS['server']])) {
return false;
}
$GLOBALS['PHP_AUTH_USER'] = $this->blowfishDecrypt(
$GLOBALS['PHP_AUTH_USER'] = $this->cookieDecrypt(
$_COOKIE['pmaUser-' . $GLOBALS['server']],
$this->_getBlowfishSecret()
$this->_getEncryptionSecret()
);
// user was never logged in since session start
@ -401,18 +377,24 @@ class AuthenticationCookie extends AuthenticationPlugin
exit;
}
// password
if (empty($_COOKIE['pmaPass-' . $GLOBALS['server']])) {
// check password cookie
if (empty($_COOKIE['pmaAuth-' . $GLOBALS['server']])) {
return false;
}
$GLOBALS['PHP_AUTH_PW'] = $this->blowfishDecrypt(
$_COOKIE['pmaPass-' . $GLOBALS['server']],
$this->_getBlowfishSecret()
$auth_data = json_decode(
$this->cookieDecrypt(
$_COOKIE['pmaAuth-' . $GLOBALS['server']],
$this->_getSessionEncryptionSecret()
),
true
);
if ($GLOBALS['PHP_AUTH_PW'] == "\xff(blank)") {
$GLOBALS['PHP_AUTH_PW'] = '';
if (! is_array($auth_data) || ! isset($auth_data['password'])) {
return false;
}
$GLOBALS['PHP_AUTH_PW'] = $auth_data['password'];
if ($GLOBALS['cfg']['AllowArbitraryServer'] && ! empty($auth_data['server'])) {
$GLOBALS['pma_auth_server'] = $auth_data['server'];
}
$GLOBALS['from_cookie'] = true;
@ -431,14 +413,14 @@ class AuthenticationCookie extends AuthenticationPlugin
// Ensures valid authentication mode, 'only_db', bookmark database and
// table names and relation table name are used
if ($cfg['Server']['user'] != $GLOBALS['PHP_AUTH_USER']) {
if (! hash_equals($cfg['Server']['user'], $GLOBALS['PHP_AUTH_USER'])) {
foreach ($cfg['Servers'] as $idx => $current) {
if ($current['host'] == $cfg['Server']['host']
&& $current['port'] == $cfg['Server']['port']
&& $current['socket'] == $cfg['Server']['socket']
&& $current['ssl'] == $cfg['Server']['ssl']
&& $current['connect_type'] == $cfg['Server']['connect_type']
&& $current['user'] == $GLOBALS['PHP_AUTH_USER']
&& hash_equals($current['user'], $GLOBALS['PHP_AUTH_USER'])
) {
$GLOBALS['server'] = $idx;
$cfg['Server'] = $current;
@ -475,47 +457,26 @@ class AuthenticationCookie extends AuthenticationPlugin
unset($_SERVER['PHP_AUTH_PW']);
$_SESSION['last_access_time'] = time();
}
/**
* Stores user credentials after successful login.
*
* @return void
*/
public function storeUserCredentials()
{
global $cfg;
// Name and password cookies need to be refreshed each time
// Duration = one month for username
$GLOBALS['PMA_Config']->setCookie(
'pmaUser-' . $GLOBALS['server'],
$this->blowfishEncrypt(
$cfg['Server']['user'],
$this->_getBlowfishSecret()
)
);
$this->storeUsernameCookie($cfg['Server']['user']);
// Duration = as configured
$GLOBALS['PMA_Config']->setCookie(
'pmaPass-' . $GLOBALS['server'],
$this->blowfishEncrypt(
! empty($cfg['Server']['password'])
? $cfg['Server']['password'] : "\xff(blank)",
$this->_getBlowfishSecret()
),
null,
$GLOBALS['cfg']['LoginCookieStore']
);
$this->storePasswordCookie($cfg['Server']['password']);
// Set server cookies if required (once per session) and, in this case,
// force reload to ensure the client accepts cookies
if (! $GLOBALS['from_cookie']) {
if ($GLOBALS['cfg']['AllowArbitraryServer']) {
if (! empty($GLOBALS['pma_auth_server'])) {
// Duration = one month for servername
$GLOBALS['PMA_Config']->setCookie(
'pmaServer-' . $GLOBALS['server'],
$cfg['Server']['host']
);
} else {
// Delete servername cookie
$GLOBALS['PMA_Config']->removeCookie(
'pmaServer-' . $GLOBALS['server']
);
}
}
// URL where to go:
$redirect_url = $cfg['PmaAbsoluteUri'] . 'index.php';
@ -549,7 +510,51 @@ class AuthenticationCookie extends AuthenticationPlugin
} // end if
return true;
}
/**
* Stores username in a cookie.
*
* @param string $username User name
*
* @return void
*/
public function storeUsernameCookie($username)
{
// Name and password cookies need to be refreshed each time
// Duration = one month for username
$GLOBALS['PMA_Config']->setCookie(
'pmaUser-' . $GLOBALS['server'],
$this->cookieEncrypt(
$username,
$this->_getEncryptionSecret()
)
);
}
/**
* Stores password in a cookie.
*
* @param string $password Password
*
* @return void
*/
public function storePasswordCookie($password)
{
$payload = array('password' => $password);
if ($GLOBALS['cfg']['AllowArbitraryServer'] && ! empty($GLOBALS['pma_auth_server'])) {
$payload['server'] = $GLOBALS['pma_auth_server'];
}
// Duration = as configured
$GLOBALS['PMA_Config']->setCookie(
'pmaAuth-' . $GLOBALS['server'],
$this->cookieEncrypt(
json_encode($payload),
$this->_getSessionEncryptionSecret()
),
null,
$GLOBALS['cfg']['LoginCookieStore']
);
}
/**
@ -568,7 +573,7 @@ class AuthenticationCookie extends AuthenticationPlugin
global $conn_error;
// Deletes password cookie and displays the login form
$GLOBALS['PMA_Config']->removeCookie('pmaPass-' . $GLOBALS['server']);
$GLOBALS['PMA_Config']->removeCookie('pmaAuth-' . $GLOBALS['server']);
if (! empty($GLOBALS['login_without_password_is_forbidden'])) {
$conn_error = __(
@ -601,32 +606,120 @@ class AuthenticationCookie extends AuthenticationPlugin
*
* @return string
*/
private function _getBlowfishSecret()
private function _getEncryptionSecret()
{
if (empty($GLOBALS['cfg']['blowfish_secret'])) {
if (empty($_SESSION['auto_blowfish_secret'])) {
// this returns 23 characters
$_SESSION['auto_blowfish_secret'] = uniqid('', true);
}
return $_SESSION['auto_blowfish_secret'];
return $this->_getSessionEncryptionSecret();
} else {
// apply md5() to work around too long secrets (returns 32 characters)
return md5($GLOBALS['cfg']['blowfish_secret']);
return $GLOBALS['cfg']['blowfish_secret'];
}
}
/**
* Encryption using blowfish algorithm (mcrypt)
* or phpseclib's AES if mcrypt not available
* Returns blowfish secret or generates one if needed.
*
* @return string
*/
private function _getSessionEncryptionSecret()
{
if (empty($_SESSION['encryption_key'])) {
if ($this->_useOpenSSL()) {
$_SESSION['encryption_key'] = openssl_random_pseudo_bytes(32);
} else {
include_once "./libraries/phpseclib/Crypt/Random.php";
$_SESSION['encryption_key'] = crypt_random_string(32);
}
}
return $_SESSION['encryption_key'];
}
/**
* Checks whether we should use openssl for encryption.
*
* @return boolean
*/
private function _useOpenSSL()
{
return (
function_exists('openssl_encrypt')
&& function_exists('openssl_decrypt')
&& function_exists('openssl_random_pseudo_bytes')
&& PHP_VERSION_ID >= 50304
);
}
/**
* Concatenates secret in order to make it 16 bytes log
*
* This doesn't add any security, just ensures the secret
* is long enough by copying it.
*
* @param string $secret Original secret
*
* @return string
*/
public function enlargeSecret($secret)
{
while (strlen($secret) < 16) {
$secret .= $secret;
}
return substr($secret, 0, 16);
}
/**
* Derives MAC secret from encryption secret.
*
* @param string $secret the secret
*
* @return string the MAC secret
*/
public function getMACSecret($secret)
{
// Grab first part, up to 16 chars
// The MAC and AES secrets can overlap if original secret is short
$length = strlen($secret);
if ($length > 16) {
return substr($secret, 0, 16);
}
return $this->enlargeSecret(
$length == 1 ? $secret : substr($secret, 0, -1)
);
}
/**
* Derives AES secret from encryption secret.
*
* @param string $secret the secret
*
* @return string the AES secret
*/
public function getAESSecret($secret)
{
// Grab second part, up to 16 chars
// The MAC and AES secrets can overlap if original secret is short
$length = strlen($secret);
if ($length > 16) {
return substr($secret, -16);
}
return $this->enlargeSecret(
$length == 1 ? $secret : substr($secret, 1)
);
}
/**
* Encryption using openssl's AES or phpseclib's AES
* (phpseclib uses mcrypt when it is available)
*
* @param string $data original data
* @param string $secret the secret
*
* @return string the encrypted result
*/
public function blowfishEncrypt($data, $secret)
public function cookieEncrypt($data, $secret)
{
global $iv;
$mac_secret = $this->getMACSecret($secret);
$aes_secret = $this->getAESSecret($secret);
$iv = $this->createIV();
if (! function_exists('mcrypt_encrypt')) {
/**
* This library uses mcrypt when available, so
@ -636,10 +729,11 @@ class AuthenticationCookie extends AuthenticationPlugin
*/
include_once "./libraries/phpseclib/Crypt/AES.php";
$cipher = new Crypt_AES(CRYPT_AES_MODE_ECB);
$cipher->setKey($secret);
return base64_encode($cipher->encrypt($data));
$cipher->setIV($iv);
$cipher->setKey($aes_secret);
$result = base64_encode($cipher->encrypt($data));
} else {
return base64_encode(
$result = base64_encode(
mcrypt_encrypt(
MCRYPT_BLOWFISH,
$secret,
@ -649,6 +743,14 @@ class AuthenticationCookie extends AuthenticationPlugin
)
);
}
$iv = base64_encode($iv);
return json_encode(
array(
'iv' => $iv,
'mac' => hash_hmac('sha1', $iv . $result, $mac_secret),
'payload' => $result,
)
);
}
/**
@ -658,29 +760,81 @@ class AuthenticationCookie extends AuthenticationPlugin
* @param string $encdata encrypted data
* @param string $secret the secret
*
* @return string original data
* @return string|bool original data, false on error
*/
public function blowfishDecrypt($encdata, $secret)
public function cookieDecrypt($encdata, $secret)
{
global $iv;
$data = json_decode($encdata, true);
if (! is_array($data) || ! isset($data['mac']) || ! isset($data['iv']) || ! isset($data['payload'])
|| ! is_string($data['mac']) || ! is_string($data['iv']) || ! is_string($data['payload'])
) {
return false;
}
$mac_secret = $this->getMACSecret($secret);
$aes_secret = $this->getAESSecret($secret);
$newmac = hash_hmac('sha1', $data['iv'] . $data['payload'], $mac_secret);
if (! hash_equals($data['mac'], $newmac)) {
return false;
}
if (! function_exists('mcrypt_encrypt')) {
include_once "./libraries/phpseclib/Crypt/AES.php";
$cipher = new Crypt_AES(CRYPT_AES_MODE_ECB);
$cipher->setKey($secret);
return $cipher->decrypt(base64_decode($encdata));
$cipher->setIV(base64_decode($data['iv']));
$cipher->setKey($aes_secret);
return $cipher->decrypt(base64_decode($data['payload']));
} else {
$data = base64_decode($encdata);
$decrypted = mcrypt_decrypt(
MCRYPT_BLOWFISH,
$secret,
$data,
base64_decode($data['payload']),
MCRYPT_MODE_CBC,
$iv
base64_decode($data['iv'])
);
return trim($decrypted);
}
}
/**
* Returns size of IV for encryption.
*
* @return int
*/
public function getIVSize()
{
include_once "./libraries/phpseclib/Crypt/AES.php";
$cipher = new Crypt_AES(CRYPT_AES_MODE_ECB);
return $cipher->block_size;
}
/**
* Initialization
* Store the initialization vector because it will be needed for
* further decryption. I don't think necessary to have one iv
* per server so I don't put the server number in the cookie name.
*
* @return void
*/
public function createIV()
{
if (function_exists('mcrypt_create_iv')) {
srand((double) microtime() * 1000000);
$td = mcrypt_module_open(MCRYPT_BLOWFISH, '', MCRYPT_MODE_CBC, '');
if ($td === false) {
PMA_fatalError(__('Failed to use Blowfish from mcrypt!'));
}
return mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
} else {
include_once "./libraries/phpseclib/Crypt/Random.php";
return crypt_random_string(
$this->getIVSize()
);
}
}
/**
* This method is called when any PluginManager to which the observer
* is attached calls PluginManager::notify()

View File

@ -158,10 +158,13 @@ class AuthenticationHttp extends AuthenticationPlugin
unset($usr_pass);
}
// sanitize username
$PHP_AUTH_USER = PMA_sanitizeMySQLUser($PHP_AUTH_USER);
// User logged out -> ensure the new username is not the same
$old_usr = isset($_REQUEST['old_usr']) ? $_REQUEST['old_usr'] : '';
if (! empty($old_usr)
&& (isset($PHP_AUTH_USER) && $old_usr == $PHP_AUTH_USER)
&& (isset($PHP_AUTH_USER) && hash_equals($old_usr, $PHP_AUTH_USER))
) {
$PHP_AUTH_USER = '';
// -> delete user's choices that were stored in session
@ -194,12 +197,12 @@ class AuthenticationHttp extends AuthenticationPlugin
// Ensures valid authentication mode, 'only_db', bookmark database and
// table names and relation table name are used
if ($cfg['Server']['user'] != $PHP_AUTH_USER) {
if (! hash_equals($cfg['Server']['user'], $PHP_AUTH_USER)) {
$servers_cnt = count($cfg['Servers']);
for ($i = 1; $i <= $servers_cnt; $i++) {
if (isset($cfg['Servers'][$i])
&& ($cfg['Servers'][$i]['host'] == $cfg['Server']['host']
&& $cfg['Servers'][$i]['user'] == $PHP_AUTH_USER)
&& hash_equals($cfg['Servers'][$i]['user'], $PHP_AUTH_USER))
) {
$server = $i;
$cfg['Server'] = $cfg['Servers'][$i];

View File

@ -1,172 +0,0 @@
<?php
/**
* @package Swekey
*/
?>
<script>
var g_SwekeyPlugin = null;
// -------------------------------------------------------------------
// Create the swekey plugin if it does not exists
function Swekey_Plugin()
{
try
{
if (g_SwekeyPlugin != null)
return g_SwekeyPlugin;
if (window.ActiveXObject)
{
g_SwekeyPlugin = document.getElementById("swekey_activex");
if (g_SwekeyPlugin == null)
{
// we must create the activex that way instead of new ActiveXObject("FbAuthAx.FbAuthCtl");
// ortherwise SetClientSite is not called and we can not get the url
var div = document.createElement('div');
div.innerHTML='<object id="swekey_activex" style="display:none" CLASSID="CLSID:8E02E3F9-57AA-4EE1-AA68-A42DD7B0FADE"></object>';
// Never append to the body because it may still loading and it breaks IE
document.body.insertBefore(div, document.body.firstChild);
g_SwekeyPlugin = document.getElementById("swekey_activex");
}
return g_SwekeyPlugin;
}
g_SwekeyPlugin = document.getElementById("swekey_plugin");
if (g_SwekeyPlugin != null)
return g_SwekeyPlugin;
for (i = 0; i < navigator.plugins.length; i ++)
{
try
{
if (navigator.plugins[i] == null)
{
navigator.plugins.refresh();
}
else if (navigator.plugins[i][0] != null && navigator.plugins[i][0].type == "application/fbauth-plugin")
{
var x = document.createElement('embed');
x.setAttribute('type', 'application/fbauth-plugin');
x.setAttribute('id', 'swekey_plugin');
x.setAttribute('width', '0');
x.setAttribute('height', '0');
x.style.dislay='none';
//document.body.appendChild(x);
document.body.insertBefore(x, document.body.firstChild);
g_SwekeyPlugin = document.getElementById("swekey_plugin");
return g_SwekeyPlugin;
}
}
catch (e)
{
navigator.plugins.refresh();
//alert ('Failed to create plugin: ' + e);
}
}
}
catch (e)
{
//alert("Swekey_Plugin " + e);
g_SwekeyPlugin = null;
}
return null;
}
// -------------------------------------------------------------------
// Returns true if the swekey plugin is installed
function Swekey_Installed()
{
return (Swekey_Plugin() != null);
}
// -------------------------------------------------------------------
// List the id of the Swekey connected to the PC
// Returns a string containing comma separated Swekey Ids
// A Swekey is a 32 char hexadecimal value.
function Swekey_ListKeyIds()
{
try
{
return Swekey_Plugin().list();
}
catch (e)
{
// alert("Swekey_ListKeyIds " + e);
}
return "";
}
// -------------------------------------------------------------------
// Ask the Connected Swekey to generate an OTP
// id: The id of the connected Swekey (returne by Swekey_ListKeyIds())
// rt: A random token
// return: The calculated OTP encoded in a 64 chars hexadecimal value.
function Swekey_GetOtp(id, rt)
{
try
{
return Swekey_Plugin().getotp(id, rt);
}
catch (e)
{
// alert("Swekey_GetOtp " + e);
}
return "";
}
// -------------------------------------------------------------------
// Ask the Connected Swekey to generate a OTP linked to the current https host
// id: The id of the connected Swekey (returne by Swekey_ListKeyIds())
// rt: A random token
// return: The calculated OTP encoded in a 64 chars hexadecimal value.
// or "" if the current url does not start with https
function Swekey_GetLinkedOtp(id, rt)
{
try
{
return Swekey_Plugin().getlinkedotp(id, rt);
}
catch (e)
{
// alert("Swekey_GetSOtp " + e);
}
return "";
}
// -------------------------------------------------------------------
// Calls Swekey_GetOtp or Swekey_GetLinkedOtp depending if we are in
// an https page or not.
// id: The id of the connected Swekey (returne by Swekey_ListKeyIds())
// rt: A random token
// return: The calculated OTP encoded in a 64 chars hexadecimal value.
function Swekey_GetSmartOtp(id, rt)
{
var res = Swekey_GetLinkedOtp(id, rt);
if (res == "")
res = Swekey_GetOtp(id, rt);
return res;
}
// -------------------------------------------------------------------
// Set a unplug handler (url) to the specified connected feebee
// id: The id of the connected Swekey (returne by Swekey_ListKeyIds())
// key: The key that index that url, (aplhanumeric values only)
// url: The url that will be launched ("" deletes the url)
function Swekey_SetUnplugUrl(id, key, url)
{
try
{
return Swekey_Plugin().setunplugurl(id, key, url);
}
catch (e)
{
// alert("Swekey_SetUnplugUrl " + e);
}
}
</script>

View File

@ -1,25 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIEKjCCAxKgAwIBAgIJAMjw7QcLWCd6MA0GCSqGSIb3DQEBBQUAMGsxCzAJBgNV
BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRQwEgYDVQQKEwtNdXNiZSwgSW5j
LjESMBAGA1UEAxMJbXVzYmUuY29tMR0wGwYJKoZIhvcNAQkBFg5pbmZvQG11c2Jl
LmNvbTAeFw0wODA5MDQxNDE2MTNaFw0zNzEyMjExNDE2MTNaMGsxCzAJBgNVBAYT
AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRQwEgYDVQQKEwtNdXNiZSwgSW5jLjES
MBAGA1UEAxMJbXVzYmUuY29tMR0wGwYJKoZIhvcNAQkBFg5pbmZvQG11c2JlLmNv
bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOBhOljxVzQfK4gted2I
d3BemcjW4abAUOzn3KYWXpPO5xIfVeXNDGkDbyH+X+7fo94sX25/ewuKNFDSOcvo
tXHq7uQenTHB35r+a+LY81KceUHgW90a3XsqPAkwAjyYcgo3zmM2DtLvw+5Yod8T
wAHk9m3qavnQ1uk99jBTwL7RZ9jIZHh9pFCL93uJc2obtd8O96Iycbn2q0w/AWbb
+eUVWIHzvLtfPvROeL3lJzr/Uz5LjKapxJ3qyqASflfHpnj9pU8l6g2TQ6Hg5KT5
tLFkRe7uGhOfRtOQ/+NjaWrEuNCFnpyN4Q5Fv+5qA1Ip1IpH0200sWbAf/k2u0Qp
Sx0CAwEAAaOB0DCBzTAdBgNVHQ4EFgQUczJrQ7hCvtsnzcqiDIZ/GSn/CiwwgZ0G
A1UdIwSBlTCBkoAUczJrQ7hCvtsnzcqiDIZ/GSn/Ciyhb6RtMGsxCzAJBgNVBAYT
AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRQwEgYDVQQKEwtNdXNiZSwgSW5jLjES
MBAGA1UEAxMJbXVzYmUuY29tMR0wGwYJKoZIhvcNAQkBFg5pbmZvQG11c2JlLmNv
bYIJAMjw7QcLWCd6MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAGxk
8xzIljeBDQWWVRr0NEALVSv3i09V4jAKkyEOfmZ8lKMKJi0atwbtjrXTzLnNYj+Q
pyUbyY/8ItWvV7pnVxMiF9qcer7e9X4vw358GZuMVE/da1nWxz+CwzTm5oO30RzA
antM9bISFFr9lJq69bDWOnCUi1IG8DSL3TxtlABso7S4vqiZ+sB33l6k1K4a/Njb
QkU9UejKhKkVVZTsOrumfnOJ4MCmPfX8Y/AY2o670y5HnzpxerIYziCVzApPVrW7
sKH0tuVGturMfQOKgstYe4/m9glBTeTLMkjD+6MJC2ONBD7GAiOO95gNl5M1fzJQ
FEe5CJ7DCYl0GdmLXXw=
-----END CERTIFICATE-----

View File

@ -1,297 +0,0 @@
<?php
/**
* @package Swekey
*/
if (! defined('PHPMYADMIN')) {
exit;
}
/**
* Checks Swekey authentication.
*/
function Swekey_auth_check()
{
global $cfg;
$confFile = $cfg['Server']['auth_swekey_config'];
if (! isset($_SESSION['SWEKEY'])) {
$_SESSION['SWEKEY'] = array();
}
$_SESSION['SWEKEY']['ENABLED'] = (! empty($confFile) && file_exists($confFile));
// Load the swekey.conf file the first time
if ($_SESSION['SWEKEY']['ENABLED']
&& empty($_SESSION['SWEKEY']['CONF_LOADED'])
) {
$_SESSION['SWEKEY']['CONF_LOADED'] = true;
$_SESSION['SWEKEY']['VALID_SWEKEYS'] = array();
$valid_swekeys = explode("\n", @file_get_contents($confFile));
foreach ($valid_swekeys as $line) {
if (preg_match("/^[0-9A-F]{32}:.+$/", $line) != false) {
$items = explode(":", $line);
if (count($items) == 2) {
$_SESSION['SWEKEY']['VALID_SWEKEYS'][$items[0]] = trim($items[1]);
}
} elseif (preg_match("/^[A-Z_]+=.*$/", $line) != false) {
$items = explode("=", $line);
$_SESSION['SWEKEY']['CONF_'.trim($items[0])] = trim($items[1]);
}
}
// Set default values for settings
if (! isset($_SESSION['SWEKEY']['CONF_SERVER_CHECK'])) {
$_SESSION['SWEKEY']['CONF_SERVER_CHECK'] = "";
}
if (! isset($_SESSION['SWEKEY']['CONF_SERVER_RNDTOKEN'])) {
$_SESSION['SWEKEY']['CONF_SERVER_RNDTOKEN'] = "";
}
if (! isset($_SESSION['SWEKEY']['CONF_SERVER_STATUS'])) {
$_SESSION['SWEKEY']['CONF_SERVER_STATUS'] = "";
}
if (! isset($_SESSION['SWEKEY']['CONF_CA_FILE'])) {
$_SESSION['SWEKEY']['CONF_CA_FILE'] = "";
}
if (! isset($_SESSION['SWEKEY']['CONF_ENABLE_TOKEN_CACHE'])) {
$_SESSION['SWEKEY']['CONF_ENABLE_TOKEN_CACHE'] = true;
}
if (! isset($_SESSION['SWEKEY']['CONF_DEBUG'])) {
$_SESSION['SWEKEY']['CONF_DEBUG'] = false;
}
}
// check if a web key has been authenticated
if ($_SESSION['SWEKEY']['ENABLED']) {
if (empty($_SESSION['SWEKEY']['AUTHENTICATED_SWEKEY'])) {
return false;
}
}
return true;
}
/**
* Handle Swekey authentication error.
*/
function Swekey_auth_error()
{
if (! isset($_SESSION['SWEKEY'])) {
return null;
}
if (! $_SESSION['SWEKEY']['ENABLED']) {
return null;
}
include_once './libraries/plugins/auth/swekey/authentication.inc.php';
?>
<script>
function Swekey_GetValidKey()
{
var valids = "<?php
foreach ($_SESSION['SWEKEY']['VALID_SWEKEYS'] as $key => $value) {
echo $key.',';
}
?>";
var connected_keys = Swekey_ListKeyIds().split(",");
for (i in connected_keys) {
if (connected_keys[i] != null && connected_keys[i].length == 32) {
if (valids.indexOf(connected_keys[i]) >= 0) {
return connected_keys[i];
}
}
}
if (connected_keys.length > 0) {
if (connected_keys[0].length == 32) {
return "unknown_key_" + connected_keys[0];
}
}
return "none";
}
var key = Swekey_GetValidKey();
function timedCheck()
{
if (key != Swekey_GetValidKey()) {
window.location.search = "?swekey_reset";
} else {
setTimeout("timedCheck()",1000);
}
}
setTimeout("timedCheck()",1000);
</script>
<?php
if (! empty($_SESSION['SWEKEY']['AUTHENTICATED_SWEKEY'])) {
return null;
}
if (count($_SESSION['SWEKEY']['VALID_SWEKEYS']) == 0) {
return sprintf(__('File %s does not contain any key id'), $GLOBALS['cfg']['Server']['auth_swekey_config']);
}
include_once "libraries/plugins/auth/swekey/swekey.php";
Swekey_SetCheckServer($_SESSION['SWEKEY']['CONF_SERVER_CHECK']);
Swekey_SetRndTokenServer($_SESSION['SWEKEY']['CONF_SERVER_RNDTOKEN']);
Swekey_SetStatusServer($_SESSION['SWEKEY']['CONF_SERVER_STATUS']);
Swekey_EnableTokenCache($_SESSION['SWEKEY']['CONF_ENABLE_TOKEN_CACHE']);
$caFile = $_SESSION['SWEKEY']['CONF_CA_FILE'];
if (empty($caFile)) {
$caFile = __FILE__;
$pos = strrpos($caFile, '/');
if ($pos === false) {
$pos = strrpos($caFile, '\\'); // windows
}
$caFile = substr($caFile, 0, $pos + 1).'musbe-ca.crt';
// echo "\n<!-- $caFile -->\n";
// if (file_exists($caFile))
// echo "<!-- exists -->\n";
}
if (file_exists($caFile)) {
Swekey_SetCAFile($caFile);
} elseif (! empty($caFile) && (substr($_SESSION['SWEKEY']['CONF_SERVER_CHECK'], 0, 8) == "https://")) {
return "Internal Error: CA File $caFile not found";
}
$result = null;
$swekey_id = $_GET['swekey_id'];
$swekey_otp = $_GET['swekey_otp'];
if (isset($swekey_id)) {
unset($_SESSION['SWEKEY']['AUTHENTICATED_SWEKEY']);
if (! isset($_SESSION['SWEKEY']['RND_TOKEN'])) {
unset($swekey_id);
} else {
if (strlen($swekey_id) == 32) {
$res = Swekey_CheckOtp($swekey_id, $_SESSION['SWEKEY']['RND_TOKEN'], $swekey_otp);
unset($_SESSION['SWEKEY']['RND_TOKEN']);
if (! $res) {
$result = __('Hardware authentication failed') . ' (' . Swekey_GetLastError() . ')';
} else {
$_SESSION['SWEKEY']['AUTHENTICATED_SWEKEY'] = $swekey_id;
$_SESSION['SWEKEY']['FORCE_USER'] = $_SESSION['SWEKEY']['VALID_SWEKEYS'][$swekey_id];
return null;
}
} else {
$result = __('No valid authentication key plugged');
if ($_SESSION['SWEKEY']['CONF_DEBUG']) {
$result .= "<br/>" . htmlspecialchars($swekey_id);
}
unset($_SESSION['SWEKEY']['CONF_LOADED']); // reload the conf file
}
}
} else {
unset($_SESSION['SWEKEY']);
}
$_SESSION['SWEKEY']['RND_TOKEN'] = Swekey_GetFastRndToken();
if (strlen($_SESSION['SWEKEY']['RND_TOKEN']) != 64) {
$result = __('Hardware authentication failed') . ' (' . Swekey_GetLastError() . ')';
unset($_SESSION['SWEKEY']['CONF_LOADED']); // reload the conf file
}
if (! isset($swekey_id)) {
?>
<script>
if (key.length != 32) {
window.location.search="?swekey_id=" + key + "&token=<?php echo $_SESSION[' PMA_token ']; ?>";
} else {
var url = "" + window.location;
if (url.indexOf("?") > 0) {
url = url.substr(0, url.indexOf("?"));
}
Swekey_SetUnplugUrl(key, "pma_login", url + "?session_to_unset=<?php echo session_id();?>&token=<?php echo $_SESSION[' PMA_token ']; ?>");
var otp = Swekey_GetOtp(key, <?php echo '"'.$_SESSION['SWEKEY']['RND_TOKEN'].'"';?>);
window.location.search="?swekey_id=" + key + "&swekey_otp=" + otp + "&token=<?php echo $_SESSION[' PMA_token ']; ?>";
}
</script>
<?php
return __('Authenticating…');
}
return $result;
}
/**
* Perform login using Swekey.
*/
function Swekey_login($input_name, $input_go)
{
$swekeyErr = Swekey_auth_error();
if ($swekeyErr != null) {
PMA_Message::error($swekeyErr)->display();
if ($GLOBALS['error_handler']->hasDisplayErrors()) {
echo '<div>';
$GLOBALS['error_handler']->dispErrors();
echo '</div>';
}
}
if (isset($_SESSION['SWEKEY']) && $_SESSION['SWEKEY']['ENABLED']) {
echo '<script type="text/javascript">';
if (empty($_SESSION['SWEKEY']['FORCE_USER'])) {
echo 'var user = null;';
} else {
echo 'var user = "'.$_SESSION['SWEKEY']['FORCE_USER'].'";';
}
?>
function open_swekey_site()
{
window.open("<?php echo PMA_linkURL('http://phpmyadmin.net/auth_key'); ?>");
}
var input_username = document.getElementById("<?php echo $input_name; ?>");
var input_go = document.getElementById("<?php echo $input_go; ?>");
var swekey_status = document.createElement('img');
swekey_status.setAttribute('onclick', 'open_swekey_site()');
swekey_status.setAttribute('style', 'width:8px; height:16px; border:0px; vspace:0px; hspace:0px; frameborder:no');
if (user == null) {
swekey_status.setAttribute('src', 'http://artwork.swekey.com/unplugged-8x16.png');
//swekey_status.setAttribute('title', 'No swekey plugged');
input_go.disabled = true;
} else {
swekey_status.setAttribute('src', 'http://artwork.swekey.com/plugged-8x16.png');
//swekey_status.setAttribute('title', 'swekey plugged');
input_username.value = user;
}
input_username.readOnly = true;
if (input_username.nextSibling == null) {
input_username.parentNode.appendChild(swekey_status);
} else {
input_username.parentNode.insertBefore(swekey_status, input_username.nextSibling);
}
<?php
echo '</script>';
}
}
if (!empty($_GET['session_to_unset'])) {
session_write_close();
session_id($_GET['session_to_unset']);
session_start();
$_SESSION = array();
session_write_close();
session_destroy();
exit;
}
if (isset($_GET['swekey_reset'])) {
unset($_SESSION['SWEKEY']);
}
?>

View File

@ -1,522 +0,0 @@
<?php
/**
* Library that provides common functions that are used to help integrating Swekey Authentication in a PHP web site
* Version 1.0
*
* History:
* 1.2 Use curl (widely installed) to query the server
* Fixed a possible tempfile race attack
* Random token cache can now be disabled
* 1.1 Added Swekey_HttpGet function that support faulty servers
* Support for custom servers
* 1.0 First release
*
* @package Swekey
*/
/**
* Errors codes
*/
define("SWEKEY_ERR_INVALID_DEV_STATUS", 901); // The satus of the device is not SWEKEY_STATUS_OK
define("SWEKEY_ERR_INTERNAL", 902); // Should never occurd
define("SWEKEY_ERR_OUTDATED_RND_TOKEN", 910); // You random token is too old
define("SWEKEY_ERR_INVALID_OTP", 911); // The otp was not correct
/**
* Those errors are considered as an attack and your site will be blacklisted during one minute
* if you receive one of those errors
*/
define("SWEKEY_ERR_BADLY_ENCODED_REQUEST", 920);
define("SWEKEY_ERR_INVALID_RND_TOKEN", 921);
define("SWEKEY_ERR_DEV_NOT_FOUND", 922);
/**
* Default values for configuration.
*/
define('SWEKEY_DEFAULT_CHECK_SERVER', 'https://auth-check.musbe.net');
define('SWEKEY_DEFAULT_RND_SERVER', 'https://auth-rnd-gen.musbe.net');
define('SWEKEY_DEFAULT_STATUS_SERVER', 'https://auth-status.musbe.net');
/**
* The last error of an operation is alway put in this global var
*/
global $gSwekeyLastError;
$gSwekeyLastError = 0;
global $gSwekeyLastResult;
$gSwekeyLastResult = "<not set>";
/**
* Servers addresses
* Use the Swekey_SetXxxServer($server) functions to set them
*/
global $gSwekeyCheckServer;
if (! isset($gSwekeyCheckServer)) {
$gSwekeyCheckServer = SWEKEY_DEFAULT_CHECK_SERVER;
}
global $gSwekeyRndTokenServer;
if (! isset($gSwekeyRndTokenServer)) {
$gSwekeyRndTokenServer = SWEKEY_DEFAULT_RND_SERVER;
}
global $gSwekeyStatusServer;
if (! isset($gSwekeyStatusServer)) {
$gSwekeyStatusServer = SWEKEY_DEFAULT_STATUS_SERVER;
}
global $gSwekeyCA;
global $gSwekeyTokenCacheEnabled;
if (! isset($gSwekeyTokenCacheEnabled)) {
$gSwekeyTokenCacheEnabled = true;
}
/**
* Change the address of the Check server.
* If $server is empty the default value 'http://auth-check.musbe.net' will be used
*
* @param server The protocol and hostname to use
*
* @access public
*/
function Swekey_SetCheckServer($server)
{
global $gSwekeyCheckServer;
if (empty($server)) {
$gSwekeyCheckServer = SWEKEY_DEFAULT_CHECK_SERVER;
} else {
$gSwekeyCheckServer = $server;
}
}
/**
* Change the address of the Random Token Generator server.
* If $server is empty the default value 'http://auth-rnd-gen.musbe.net' will be used
*
* @param server The protocol and hostname to use
*
* @access public
*/
function Swekey_SetRndTokenServer($server)
{
global $gSwekeyRndTokenServer;
if (empty($server)) {
$gSwekeyRndTokenServer = SWEKEY_DEFAULT_RND_SERVER;
} else {
$gSwekeyRndTokenServer = $server;
}
}
/**
* Change the address of the Satus server.
* If $server is empty the default value 'http://auth-status.musbe.net' will be used
*
* @param server The protocol and hostname to use
*
* @access public
*/
function Swekey_SetStatusServer($server)
{
global $gSwekeyStatusServer;
if (empty($server)) {
$gSwekeyStatusServer = SWEKEY_DEFAULT_STATUS_SERVER;
} else {
$gSwekeyStatusServer = $server;
}
}
/**
* Change the certificat file in case of the the severs use https instead of http
*
* @param cafile The path of the crt file to use
*
* @access public
*/
function Swekey_SetCAFile($cafile)
{
global $gSwekeyCA;
$gSwekeyCA = $cafile;
}
/**
* Enable or disable the random token caching
* Because everybody has full access to the cache file, it can be a DOS vulnerability
* So disable it if you are running in a non secure enviromnement
*
* @param $enable
*
* @access public
*/
function Swekey_EnableTokenCache($enable)
{
global $gSwekeyTokenCacheEnabled;
$gSwekeyTokenCacheEnabled = ! empty($enable);
}
/**
* Return the last error.
*
* @return The Last Error
* @access public
*/
function Swekey_GetLastError()
{
global $gSwekeyLastError;
return $gSwekeyLastError;
}
/**
* Return the last result.
*
* @return The Last Error
* @access public
*/
function Swekey_GetLastResult()
{
global $gSwekeyLastResult;
return $gSwekeyLastResult;
}
/**
* Send a synchronous request to the server.
* This function manages timeout then will not block if one of the server is down
*
* @param url The url to get
* @param response_code The response code
*
* @return The body of the response or "" in case of error
* @access private
*/
function Swekey_HttpGet($url, &$response_code)
{
global $gSwekeyLastError;
$gSwekeyLastError = 0;
global $gSwekeyLastResult;
$gSwekeyLastResult = "<not set>";
// use curl if available
if (function_exists('curl_init')) {
$sess = curl_init($url);
if (substr($url, 0, 8) == "https://") {
global $gSwekeyCA;
if (! empty($gSwekeyCA)) {
if (file_exists($gSwekeyCA)) {
if (! curl_setopt($sess, CURLOPT_CAINFO, $gSwekeyCA)) {
error_log("SWEKEY_ERROR:Could not set CA file : ".curl_error($sess));
} else {
$caFileOk = true;
}
} else {
error_log("SWEKEY_ERROR:Could not find CA file $gSwekeyCA getting $url");
}
}
curl_setopt($sess, CURLOPT_SSL_VERIFYHOST, '2');
curl_setopt($sess, CURLOPT_SSL_VERIFYPEER, '2');
curl_setopt($sess, CURLOPT_CONNECTTIMEOUT, '20');
curl_setopt($sess, CURLOPT_TIMEOUT, '20');
} else {
curl_setopt($sess, CURLOPT_CONNECTTIMEOUT, '3');
curl_setopt($sess, CURLOPT_TIMEOUT, '5');
}
curl_setopt($sess, CURLOPT_RETURNTRANSFER, '1');
$res=curl_exec($sess);
$response_code = curl_getinfo($sess, CURLINFO_HTTP_CODE);
$curlerr = curl_error($sess);
curl_close($sess);
if ($response_code == 200) {
$gSwekeyLastResult = $res;
return $res;
}
if (! empty($response_code)) {
$gSwekeyLastError = $response_code;
error_log("SWEKEY_ERROR:Error $gSwekeyLastError ($curlerr) getting $url");
return "";
}
$response_code = 408; // Request Timeout
$gSwekeyLastError = $response_code;
error_log("SWEKEY_ERROR:Error $curlerr getting $url");
return "";
}
// use pecl_http if available
if (class_exists('HttpRequest')) {
// retry if one of the server is down
for ($num=1; $num <= 3; $num++ ) {
$r = new HttpRequest($url);
$options = array('timeout' => '3');
if (substr($url, 0, 6) == "https:") {
$sslOptions = array();
$sslOptions['verifypeer'] = true;
$sslOptions['verifyhost'] = true;
$capath = __FILE__;
$name = strrchr($capath, '/');
// windows
if (empty($name)) {
$name = strrchr($capath, '\\');
}
$capath = substr($capath, 0, strlen($capath) - strlen($name) + 1).'musbe-ca.crt';
if (! empty($gSwekeyCA)) {
$sslOptions['cainfo'] = $gSwekeyCA;
}
$options['ssl'] = $sslOptions;
}
$r->setOptions($options);
// try
{
$reply = $r->send();
$res = $reply->getBody();
$info = $r->getResponseInfo();
$response_code = $info['response_code'];
if ($response_code != 200) {
$gSwekeyLastError = $response_code;
error_log("SWEKEY_ERROR:Error ".$gSwekeyLastError." getting ".$url);
return "";
}
$gSwekeyLastResult = $res;
return $res;
}
// catch (HttpException $e)
// {
// error_log("SWEKEY_WARNING:HttpException ".$e." getting ".$url);
// }
}
$response_code = 408; // Request Timeout
$gSwekeyLastError = $response_code;
error_log("SWEKEY_ERROR:Error ".$gSwekeyLastError." getting ".$url);
return "";
}
global $http_response_header;
$res = @file_get_contents($url);
$response_code = substr($http_response_header[0], 9, 3); //HTTP/1.0
if ($response_code == 200) {
$gSwekeyLastResult = $res;
return $res;
}
$gSwekeyLastError = $response_code;
error_log("SWEKEY_ERROR:Error ".$response_code." getting ".$url);
return "";
}
/**
* Get a Random Token from a Token Server
* The RT is a 64 vhars hexadecimal value
* You should better use Swekey_GetFastRndToken() for performance
* @access public
*/
function Swekey_GetRndToken()
{
global $gSwekeyRndTokenServer;
return Swekey_HttpGet($gSwekeyRndTokenServer.'/FULL-RND-TOKEN', $response_code);
}
/**
* Get a Half Random Token from a Token Server
* The RT is a 64 vhars hexadecimal value
* Use this value if you want to make your own Swekey_GetFastRndToken()
* @access public
*/
function Swekey_GetHalfRndToken()
{
global $gSwekeyRndTokenServer;
return Swekey_HttpGet($gSwekeyRndTokenServer.'/HALF-RND-TOKEN', $response_code);
}
/**
* Get a Half Random Token
* The RT is a 64 vhars hexadecimal value
* This function get a new random token and reuse it.
* Token are refetched from the server only once every 30 seconds.
* You should always use this function to get half random token.
* @access public
*/
function Swekey_GetFastHalfRndToken()
{
global $gSwekeyTokenCacheEnabled;
$res = "";
$cachefile = "";
// We check if we have a valid RT is the session
if (isset($_SESSION['rnd-token-date'])) {
if (time() - $_SESSION['rnd-token-date'] < 30) {
$res = $_SESSION['rnd-token'];
}
}
// If not we try to get it from a temp file (PHP >= 5.2.1 only)
if (strlen($res) != 32 && $gSwekeyTokenCacheEnabled) {
if (function_exists('sys_get_temp_dir')) {
$tempdir = sys_get_temp_dir();
$cachefile = $tempdir."/swekey-rnd-token-".get_current_user();
$modif = filemtime($cachefile);
if ($modif != false) {
if (time() - $modif < 30) {
$res = @file_get_contents($cachefile);
if (strlen($res) != 32) {
$res = "";
} else {
$_SESSION['rnd-token'] = $res;
$_SESSION['rnd-token-date'] = $modif;
}
}
}
}
}
// If we don't have a valid RT here we have to get it from the server
if (strlen($res) != 32) {
$res = substr(Swekey_GetHalfRndToken(), 0, 32);
$_SESSION['rnd-token'] = $res;
$_SESSION['rnd-token-date'] = time();
if (! empty($cachefile)) {
// we unlink the file so no possible tempfile race attack
unlink($cachefile);
$file = fopen($cachefile, "x");
if ($file != false) {
@fwrite($file, $res);
@fclose($file);
}
}
}
return $res."00000000000000000000000000000000";
}
/**
* Get a Random Token
* The RT is a 64 vhars hexadecimal value
* This function generates a unique random token for each call but call the
* server only once every 30 seconds.
* You should always use this function to get random token.
* @access public
*/
function Swekey_GetFastRndToken()
{
$res = Swekey_GetFastHalfRndToken();
if (strlen($res) == 64) {
return substr($res, 0, 32).strtoupper(md5("Musbe Authentication Key" . mt_rand() . date(DATE_ATOM)));
}
return "";
}
/**
* Checks that an OTP generated by a Swekey is valid
*
* @param id The id of the swekey
* @param rt The random token used to generate the otp
* @param otp The otp generated by the swekey
*
* @return true or false
* @access public
*/
function Swekey_CheckOtp($id, $rt, $otp)
{
global $gSwekeyCheckServer;
$res = Swekey_HttpGet($gSwekeyCheckServer.'/CHECK-OTP/'.$id.'/'.$rt.'/'.$otp, $response_code);
return $response_code == 200 && $res == "OK";
}
/**
* Values that are associated with a key.
* The following values can be returned by the Swekey_GetStatus() function
*/
define("SWEKEY_STATUS_OK", 0);
define("SWEKEY_STATUS_NOT_FOUND", 1); // The key does not exist in the db
define("SWEKEY_STATUS_INACTIVE", 2); // The key has never been activated
define("SWEKEY_STATUS_LOST", 3); // The user has lost his key
define("SWEKEY_STATUS_STOLEN", 4); // The key was stolen
define("SWEKEY_STATUS_FEE_DUE", 5); // The annual fee was not paid
define("SWEKEY_STATUS_OBSOLETE", 6); // The hardware is no longer supported
define("SWEKEY_STATUS_UNKOWN", 201); // We could not connect to the authentication server
/**
* Values that are associated with a key.
* The Javascript Api can also return the following values
*/
define("SWEKEY_STATUS_REPLACED", 100); // This key has been replaced by a backup key
define("SWEKEY_STATUS_BACKUP_KEY", 101); // This key is a backup key that is not activated yet
define("SWEKEY_STATUS_NOTPLUGGED", 200); // This key is not plugged in the computer
/**
* Return the text corresponding to the integer status of a key
*
* @param status The status
*
* @return The text corresponding to the status
* @access public
*/
function Swekey_GetStatusStr($status)
{
switch($status)
{
case SWEKEY_STATUS_OK :
return 'OK';
case SWEKEY_STATUS_NOT_FOUND :
return 'Key does not exist in the db';
case SWEKEY_STATUS_INACTIVE :
return 'Key not activated';
case SWEKEY_STATUS_LOST :
return 'Key was lost';
case SWEKEY_STATUS_STOLEN :
return 'Key was stolen';
case SWEKEY_STATUS_FEE_DUE :
return 'The annual fee was not paid';
case SWEKEY_STATUS_OBSOLETE :
return 'Key no longer supported';
case SWEKEY_STATUS_REPLACED :
return 'This key has been replaced by a backup key';
case SWEKEY_STATUS_BACKUP_KEY :
return 'This key is a backup key that is not activated yet';
case SWEKEY_STATUS_NOTPLUGGED :
return 'This key is not plugged in the computer';
case SWEKEY_STATUS_UNKOWN :
return 'Unknow Status, could not connect to the authentication server';
}
return 'unknown status '.$status;
}
/**
* If your web site requires a key to login you should check that the key
* is still valid (has not been lost or stolen) before requiring it.
* A key can be authenticated only if its status is SWEKEY_STATUS_OK
*
* @param id The id of the swekey
*
* @return The status of the swekey
* @access public
*/
function Swekey_GetStatus($id)
{
global $gSwekeyStatusServer;
$res = Swekey_HttpGet($gSwekeyStatusServer.'/GET-STATUS/'.$id, $response_code);
if ($response_code == 200) {
return intval($res);
}
return SWEKEY_STATUS_UNKOWN;
}
?>

View File

@ -213,7 +213,7 @@ class ExportLatex extends ExportPlugin
$head = '% phpMyAdmin LaTeX Dump' . $crlf
. '% version ' . PMA_VERSION . $crlf
. '% http://www.phpmyadmin.net' . $crlf
. '% https://www.phpmyadmin.net' . $crlf
. '%' . $crlf
. '% ' . __('Host') . ': ' . $cfg['Server']['host'];
if (! empty($cfg['Server']['port'])) {

View File

@ -344,7 +344,7 @@ class ExportMediawiki extends ExportPlugin
// see http://www.mediawiki.org/wiki/Help:Formatting
$comment = $this->_exportCRLF();
$comment .= '<!--' . $this->_exportCRLF();
$comment .= $text . $this->_exportCRLF();
$comment .= htmlspecialchars($text) . $this->_exportCRLF();
$comment .= '-->' . str_repeat($this->_exportCRLF(), 2);
return $comment;

View File

@ -82,6 +82,18 @@ class ExportPhparray extends ExportPlugin
{
}
/**
* Removes end of comment from a string
*
* @param string $string String to replace
*
* @return string
*/
public function commentString($string)
{
return strtr($string, '*/', '-');
}
/**
* Outputs export header
*
@ -119,9 +131,9 @@ class ExportPhparray extends ExportPlugin
public function exportDBHeader ($db)
{
PMA_exportOutputHandler(
'//' . $GLOBALS['crlf']
. '// Database ' . PMA_Util::backquote($db)
. $GLOBALS['crlf'] . '//' . $GLOBALS['crlf']
'/**' . $GLOBALS['crlf']
. ' * Database ' . $this->commentString(PMA_Util::backquote($db))
. $GLOBALS['crlf'] . ' */' . $GLOBALS['crlf']
);
return true;
}
@ -192,9 +204,9 @@ class ExportPhparray extends ExportPlugin
$buffer = '';
$record_cnt = 0;
// Output table name as comment
$buffer .= $crlf . '// '
. PMA_Util::backquote($db) . '.'
. PMA_Util::backquote($table) . $crlf;
$buffer .= $crlf . '/* '
. $this->commentString(PMA_Util::backquote($db)) . '.'
. $this->commentString(PMA_Util::backquote($table)) . ' */' . $crlf;
$buffer .= '$' . $tablefixed . ' = array(';
while ($record = PMA_DBI_fetch_row($result)) {

View File

@ -519,7 +519,16 @@ class ExportSql extends ExportPlugin
&& $GLOBALS['sql_include_comments']
) {
// see http://dev.mysql.com/doc/refman/5.0/en/ansi-diff-comments.html
return '--' . (empty($text) ? '' : ' ') . $text . $GLOBALS['crlf'];
if (empty($text)) {
return '--' . $GLOBALS['crlf'];
} else {
$lines = preg_split("/\\r\\n|\\r|\\n/", $text);
$result = array();
foreach ($lines as $line) {
$result[] = '-- ' . $line . $GLOBALS['crlf'];
}
return implode('', $result);
}
} else {
return '';
}
@ -605,7 +614,7 @@ class ExportSql extends ExportPlugin
}
$head = $this->_exportComment('phpMyAdmin SQL Dump')
. $this->_exportComment('version ' . PMA_VERSION)
. $this->_exportComment('http://www.phpmyadmin.net')
. $this->_exportComment('https://www.phpmyadmin.net')
. $this->_exportComment();
$host_string = __('Host') . ': ' . $cfg['Server']['host'];
if (! empty($cfg['Server']['port'])) {

View File

@ -186,9 +186,9 @@ class ExportXml extends ExportPlugin
. '<!--' . $crlf
. '- phpMyAdmin XML Dump' . $crlf
. '- version ' . PMA_VERSION . $crlf
. '- http://www.phpmyadmin.net' . $crlf
. '- https://www.phpmyadmin.net' . $crlf
. '-' . $crlf
. '- ' . __('Host') . ': ' . $cfg['Server']['host'];
. '- ' . __('Host') . ': ' . htmlspecialchars($cfg['Server']['host']);
if (! empty($cfg['Server']['port'])) {
$head .= ':' . $cfg['Server']['port'];
}
@ -201,7 +201,7 @@ class ExportXml extends ExportPlugin
$head .= '<pma_xml_export version="1.0"'
. (($export_struct)
? ' xmlns:pma="http://www.phpmyadmin.net/some_doc_url/"'
? ' xmlns:pma="https://www.phpmyadmin.net/some_doc_url/"'
: '')
. '>' . $crlf;
@ -230,7 +230,7 @@ class ExportXml extends ExportPlugin
$head .= ' -->' . $crlf;
$head .= ' <pma:structure_schemas>' . $crlf;
$head .= ' <pma:database name="' . htmlspecialchars($db)
. '" collation="' . $db_collation . '" charset="' . $db_charset
. '" collation="' . htmlspecialchars($db_collation) . '" charset="' . htmlspecialchars($db_charset)
. '">' . $crlf;
if (count($tables) == 0) {
@ -262,7 +262,7 @@ class ExportXml extends ExportPlugin
continue;
}
$head .= ' <pma:' . $type . ' name="' . $table . '">'
$head .= ' <pma:' . $type . ' name="' . htmlspecialchars($table) . '">'
. $crlf;
$tbl = " " . htmlspecialchars($tbl);
@ -280,7 +280,7 @@ class ExportXml extends ExportPlugin
foreach ($triggers as $trigger) {
$code = $trigger['create'];
$head .= ' <pma:trigger name="'
. $trigger['name'] . '">' . $crlf;
. htmlspecialchars($trigger['name']) . '">' . $crlf;
// Do some formatting
$code = substr(rtrim($code), 0, -3);
@ -305,7 +305,7 @@ class ExportXml extends ExportPlugin
if ($functions) {
foreach ($functions as $function) {
$head .= ' <pma:function name="'
. $function . '">' . $crlf;
. htmlspecialchars($function) . '">' . $crlf;
// Do some formatting
$sql = PMA_DBI_get_definition($db, 'FUNCTION', $function);
@ -330,7 +330,7 @@ class ExportXml extends ExportPlugin
if ($procedures) {
foreach ($procedures as $procedure) {
$head .= ' <pma:procedure name="'
. $procedure . '">' . $crlf;
. htmlspecialchars($procedure) . '">' . $crlf;
// Do some formatting
$sql = PMA_DBI_get_definition($db, 'PROCEDURE', $procedure);
@ -387,7 +387,7 @@ class ExportXml extends ExportPlugin
&& $GLOBALS['xml_export_contents']
) {
$head = ' <!--' . $crlf
. ' - ' . __('Database') . ': ' . '\'' . $db . '\'' . $crlf
. ' - ' . __('Database') . ': ' . '\'' . htmlspecialchars($db) . '\'' . $crlf
. ' -->' . $crlf
. ' <database name="' . htmlspecialchars($db) . '">' . $crlf;
@ -454,7 +454,7 @@ class ExportXml extends ExportPlugin
}
unset($i);
$buffer = ' <!-- ' . __('Table') . ' ' . $table . ' -->' . $crlf;
$buffer = ' <!-- ' . __('Table') . ' ' . htmlspecialchars($table) . ' -->' . $crlf;
if (! PMA_exportOutputHandler($buffer)) {
return false;
}

View File

@ -119,12 +119,15 @@ class ImportShp extends ImportPlugin
// Extract the .dbf file and point to it.
$extracted = PMA_zipExtract(
$import_file,
realpath($GLOBALS['cfg']['TempDir']),
array($dbf_file_name)
$dbf_file_name
);
if ($extracted) {
if ($extracted !== false) {
$dbf_file_path = realpath($GLOBALS['cfg']['TempDir'])
. (PMA_IS_WINDOWS ? '\\' : '/') . $dbf_file_name;
. (PMA_IS_WINDOWS ? '\\' : '/') . PMA_sanitizeFilename($dbf_file_name, true);
$handle = fopen($dbf_file_path, 'wb');
if ($handle !== false) {
fwrite($handle, $extracted);
fclose($handle);
$temp_dbf_file = true;
// Replace the .dbf with .*, as required
// by the bsShapeFiles library.
@ -134,6 +137,7 @@ class ImportShp extends ImportPlugin
$shp->FileName = $file_name;
}
}
}
} elseif (! empty($local_import_file)
&& ! empty($GLOBALS['cfg']['UploadDir'])
&& $compression == 'none'
@ -148,6 +152,14 @@ class ImportShp extends ImportPlugin
}
}
// Delete the .dbf file extracted to 'TempDir'
if ($temp_dbf_file
&& isset($dbf_file_path)
&& file_exists($dbf_file_path)
) {
unlink($dbf_file_path);
}
// Load data
$shp->loadFromFile('');
if ($shp->lastError != "") {
@ -159,14 +171,6 @@ class ImportShp extends ImportPlugin
return;
}
// Delete the .dbf file extracted to 'TempDir'
if ($temp_dbf_file
&& isset($dbf_file_path)
&& file_exists($dbf_file_path)
) {
unlink($dbf_file_path);
}
$esri_types = array(
0 => 'Null Shape',
1 => 'Point',

View File

@ -49,7 +49,7 @@ abstract class AppendTransformationsPlugin extends TransformationsPlugin
$options[0] = '';
}
//just append the option to the original text
$newtext = $buffer . htmlspecialchars($options[0]);
$newtext = htmlspecialchars($buffer) . htmlspecialchars($options[0]);
return $newtext;
}

View File

@ -12,6 +12,7 @@ if (! defined('PHPMYADMIN')) {
/* Get the transformations interface */
require_once 'libraries/plugins/TransformationsPlugin.class.php';
require_once 'libraries/js_escape.lib.php';
/**
* Provides common methods for all of the date format transformations plugins.
@ -139,11 +140,11 @@ abstract class DateFormatTransformationsPlugin extends TransformationsPlugin
} else {
$text = 'INVALID DATE TYPE';
}
$buffer = '<dfn onclick="alert(\'' . $source . '\');" title="'
. $source . '">' . $text . '</dfn>';
return '<dfn onclick="alert(\'' . PMA_jsFormat($source, false) . '\');" title="'
. htmlspecialchars($source) . '">' . htmlspecialchars($text) . '</dfn>';
} else {
return htmlspecialchars($buffer);
}
return $buffer;
}
/**

View File

@ -72,7 +72,7 @@ abstract class DownloadTransformationsPlugin extends TransformationsPlugin
'<a href="transformation_wrapper.php%s&amp;ct=application'
. '/octet-stream&amp;cn=%s" title="%s">%s</a>',
$options['wrapper_link'],
urlencode($cn),
htmlspecialchars(urlencode($cn)),
htmlspecialchars($cn),
htmlspecialchars($cn)
);

View File

@ -45,7 +45,9 @@ abstract class FormattedTransformationsPlugin extends TransformationsPlugin
*/
public function applyTransformation($buffer, $options = array(), $meta = '')
{
return $buffer;
return '<iframe srcdoc="'
. strtr($buffer, '"', '\'')
. '" sandbox=""></iframe>';
}
/**

View File

@ -45,16 +45,8 @@ abstract class ImageLinkTransformationsPlugin extends TransformationsPlugin
*/
public function applyTransformation($buffer, $options = array(), $meta = '')
{
$transform_options = array (
'string' => '<a href="transformation_wrapper.php'
. $options['wrapper_link'] . '" alt="[__BUFFER__]">[BLOB]</a>'
);
$buffer = PMA_transformation_global_html_replace(
$buffer,
$transform_options
);
return $buffer;
return '<a href="transformation_wrapper.php'
. $options['wrapper_link'] . '" alt="' . htmlspecialchars($buffer) . '">[BLOB]</a>';
}
/**

View File

@ -47,28 +47,18 @@ abstract class InlineTransformationsPlugin extends TransformationsPlugin
public function applyTransformation($buffer, $options = array(), $meta = '')
{
if (PMA_IS_GD2) {
$transform_options = array (
'string' => '<a href="transformation_wrapper.php'
return '<a href="transformation_wrapper.php'
. $options['wrapper_link']
. '" target="_blank"><img src="transformation_wrapper.php'
. '" rel="noopener noreferrer" target="_blank"><img src="transformation_wrapper.php'
. $options['wrapper_link'] . '&amp;resize=jpeg&amp;newWidth='
. (isset($options[0]) ? $options[0] : '100') . '&amp;newHeight='
. (isset($options[1]) ? $options[1] : 100)
. '" alt="[__BUFFER__]" border="0" /></a>'
);
. (isset($options[0]) ? intval($options[0]) : '100') . '&amp;newHeight='
. (isset($options[1]) ? intval($options[1]) : 100)
. '" alt="' . htmlspecialchars($buffer) . '" border="0" /></a>';
} else {
$transform_options = array (
'string' => '<img src="transformation_wrapper.php'
return '<img src="transformation_wrapper.php'
. $options['wrapper_link']
. '" alt="[__BUFFER__]" width="320" height="240" />'
);
. '" alt="' . htmlspecialchars($buffer) . '" width="320" height="240" />';
}
$buffer = PMA_transformation_global_html_replace(
$buffer,
$transform_options
);
return $buffer;
}
/**

View File

@ -45,7 +45,7 @@ abstract class LongToIPv4TransformationsPlugin extends TransformationsPlugin
public function applyTransformation($buffer, $options = array(), $meta = '')
{
if ($buffer < 0 || $buffer > 4294967295) {
return $buffer;
return htmlspecialchars($buffer);
}
return long2ip($buffer);

View File

@ -81,7 +81,7 @@ abstract class SubstringTransformationsPlugin extends TransformationsPlugin
}
}
return $newtext;
return htmlspecialchars($newtext);
}
/**

View File

@ -12,8 +12,6 @@ if (! defined('PHPMYADMIN')) {
/* Get the transformations interface */
require_once 'libraries/plugins/TransformationsPlugin.class.php';
/* For PMA_transformation_global_html_replace */
require_once 'libraries/transformations.lib.php';
/**
* Provides common methods for all of the image link transformations plugins.
@ -47,21 +45,17 @@ abstract class TextImageLinkTransformationsPlugin extends TransformationsPlugin
*/
public function applyTransformation($buffer, $options = array(), $meta = '')
{
$transform_options = array (
'string' => '<a href="' . (isset($options[0]) ? $options[0] : '')
. $buffer . '" target="_blank"><img src="'
. (isset($options[0]) ? $options[0] : '') . $buffer
. '" border="0" width="' . (isset($options[1]) ? $options[1] : 100)
. '" height="' . (isset($options[2]) ? $options[2] : 50) . '" />'
. $buffer . '</a>'
);
$buffer = PMA_transformation_global_html_replace(
$buffer,
$transform_options
);
return $buffer;
$url = (isset($options[0]) ? $options[0] : '') . $buffer;
$parsed = parse_url($url);
/* Do not allow javascript links */
if (! isset($parsed['scheme']) || ! in_array(strtolower($parsed['scheme']), array('http', 'https', 'ftp', 'mailto'))) {
return htmlspecialchars($url);
}
return '<a href="' . htmlspecialchars($url)
. '" rel="noopener noreferrer" target="_blank"><img src="' . htmlspecialchars($url)
. '" border="0" width="' . (isset($options[1]) ? intval($options[1]) : 100)
. '" height="' . (isset($options[2]) ? intval($options[2]) : 50) . '" />'
. htmlspecialchars($buffer) . '</a>';
}
/**

View File

@ -12,8 +12,6 @@ if (! defined('PHPMYADMIN')) {
/* Get the transformations interface */
require_once 'libraries/plugins/TransformationsPlugin.class.php';
/* For PMA_transformation_global_html_replace */
require_once 'libraries/transformations.lib.php';
/**
* Provides common methods for all of the link transformations plugins.
@ -47,25 +45,19 @@ abstract class TextLinkTransformationsPlugin extends TransformationsPlugin
*/
public function applyTransformation($buffer, $options = array(), $meta = '')
{
$append_part = (isset($options[2]) && $options[2]) ? '' : $buffer;
$transform_options = array (
'string' => '<a href="'
. PMA_linkURL((isset($options[0]) ? $options[0] : '') . $append_part)
$url = (isset($options[0]) ? $options[0] : '') . ((isset($options[2]) && $options[2]) ? '' : $buffer);
$parsed = parse_url($url);
/* Do not allow javascript links */
if (! isset($parsed['scheme']) || ! in_array(strtolower($parsed['scheme']), array('http', 'https', 'ftp', 'mailto'))) {
return htmlspecialchars($url);
}
return '<a href="'
. htmlspecialchars($url)
. '" title="'
. htmlspecialchars(isset($options[1]) ? $options[1] : '')
. '" target="_new">'
. '" target="_blank" rel="noopener noreferrer">'
. htmlspecialchars(isset($options[1]) ? $options[1] : $buffer)
. '</a>'
);
$buffer = PMA_transformation_global_html_replace(
$buffer,
$transform_options
);
return $buffer;
. '</a>';
}
/**

View File

@ -233,7 +233,7 @@ function PMA_replication_slave_change_master($user, $password, $host, $port,
function PMA_replication_connect_to_master($user, $password, $host = null, $port = null, $socket = null)
{
$server = array();
$server["host"] = $host;
$server["host"] = PMA_sanitizeMySQLHost($host);
$server["port"] = $port;
$server["socket"] = $socket;

View File

@ -130,7 +130,7 @@ function PMA_replication_print_status_table($type, $hidden = false, $title = tru
foreach (${"{$type}_variables"} as $variable) {
echo ' <tr class="' . ($odd_row ? 'odd' : 'even') . '">';
echo ' <td class="name">';
echo $variable;
echo htmlspecialchars($variable);
echo ' </td>';
echo ' <td class="value">';
@ -154,9 +154,9 @@ function PMA_replication_print_status_table($type, $hidden = false, $title = tru
'Replicate_Do_Table', 'Replicate_Ignore_Table',
'Replicate_Wild_Do_Table', 'Replicate_Wild_Ignore_Table');
if (in_array($variable, $variables_wrap)) {
echo str_replace(',', ', ', ${"server_{$type}_replication"}[0][$variable]);
echo htmlspecialchars(str_replace(',', ', ', ${"server_{$type}_replication"}[0][$variable]));
} else {
echo ${"server_{$type}_replication"}[0][$variable];
echo htmlspecialchars(${"server_{$type}_replication"}[0][$variable]);
}
echo '</span>';
@ -285,7 +285,7 @@ function PMA_replication_gui_master_addslaveuser()
? ''
: ' value="' . (isset($GLOBALS['new_username'])
? $GLOBALS['new_username']
: $GLOBALS['username']) . '"')
: htmlspecialchars($GLOBALS['username'])) . '"')
. ' onchange="pred_username.value = \'userdefined\';" />'
. '</div>'
. '<div class="item">'
@ -349,7 +349,7 @@ function PMA_replication_gui_master_addslaveuser()
. '</span>'
. '<input type="text" name="hostname" maxlength="'
. $hostname_length . '" value="'
. (isset($GLOBALS['hostname']) ? $GLOBALS['hostname'] : '')
. (isset($GLOBALS['hostname']) ? htmlspecialchars($GLOBALS['hostname']) : '')
. '" title="' . __('Host')
. '" onchange="pred_hostname.value = \'userdefined\';" />'
. PMA_Util::showHint(

View File

@ -248,9 +248,9 @@ function PMA_TRI_getRowForList($trigger, $rowclass = '')
$retval .= " </td>\n";
if (empty($table)) {
$retval .= " <td>\n";
$retval .= " <a href='db_triggers.php?{$url_query}"
. "&amp;table={$trigger['table']}'>"
. $trigger['table'] . "</a>\n";
$retval .= "<a href='db_triggers.php?{$url_query}"
. "&amp;table=" . urlencode($trigger['table']) . "'>"
. urlencode($trigger['table']) . "</a>";
$retval .= " </td>\n";
}
$retval .= " <td>\n";

View File

@ -59,6 +59,9 @@ function PMA_replaceBBLink($found)
$target = '';
if (! empty($found[3])) {
$target = ' target="' . $found[3] . '"';
if ($found[3] == '_blank') {
$target .= ' rel="noopener noreferrer"';
}
}
/* Construct url */

Some files were not shown because too many files have changed in this diff Show More