protect wordpress uploaded files access from non-logged-in users? - privacy

I have launched a WordPress site for a private group of people. This site serves as a public representational site, but also they make "posts" with "Private" checked, so only logged in users can see those posts. Everything would be OK, but they also upload image/document files and attach/include them to private or public posts. All is OK with public posts, but when the file is used in a private post, we assume the file is confidential. But here WordPress allows accessing any uploaded file directly via a link (URL), even if you're not logged in to the site from the browser.
I tried searching but can't find something that would actually work. Even FB private groups have this file access restriction for outsiders, GitLab also has permissions, where if you are not in a project, you can't access ANYTHING that's there. It seems like if I used WordPress/Joomla/Drupal, it would be hacking/messing around to achieve what I want.
Do you have any suggestions, maybe to access uploaded files through WordPress (PHP) and not directly via web server, so via PHP I could make some SQL queries and check in what posts that file is included and whether the user is logged in? Also maybe there are some plugins that do exactly that?
P.S. I wouldn't be asking if I knew WordPress in-and-out, but in this case, I just launched it more or less.

One option to fix this problem is to store the file contents in the database as a blob. This could be problematic if the files are large, however, as you predicted: you can ensure that the recipient is authorised before delivering the content. Another option might be to move the file when the post is saved so that it can't be accessed directly at the http endpoint.
In either of these cases, you might then use .htaccess to redirect any GET requests for files within that directory to a new php file that delivers the content. You can check to see if the user is logged in before delivery using standard WordPress function, and/ or pull the content out of the database on the fly. These options require custom code to achieve.
(Is the file being checked for malign content, and the filename being changed to something non-deterministic, by the way? This is a vector for attack.)
If you don't wish to code, you might consider a parallel installation of ownCloud or NextCloud and then in the private post, your users place a link to the file within the other service. Both of these applications provide a number of different clients for various devices, as well as the ability to restrict access to specific groups and users.

Related

Wordpress wants to install itself, rather than run the blog

We have created a duplicate of our website on a new server as part of a migration. We have a wordpress blog that is part of our website.
The docroot of the wordpress site is set as an alias in our main site. The result is that to access the site home page, the following url is used: https://www.rephunter.net/blog/.
The new environment is not available to the public at this time, and is only accessible within our VPN. When the above link to the blog is followed, instead of the expected home page of our blog, we get the page at https://www.rephunter.net/blog/wp-admin/install.php, which wants to install a new site.
The configuration in the new environment is supposedly an exact copy of our production site from some time back. The permissions on the main files is the same.
What is it that is causing the attempted blog access to be redirected to the installation script?
EDIT:
The responses so far have not really absorbed the intent of the previous information. We are not migrating in the normal sense. Rather we are testing in a new virtual environment that will eventually lead to a more normal migration.
We have an exact duplicate of our original wordpress and database environment that is running in a virtual environment with an updated protocol stack that is only accessible if you are on the VPN for that environment. As far as we can tell, there is no difference in the configuration.
For example, the parameters in wp-config.php are exactly the same as in the original installation. When php runs, it sees the same environment, with host names and everything identical. It would not work otherwise.
Yet if there really were no difference, it would just run. But since WP is trying to install a new database, there is something different that we are missing.
To further illustrate this: supposed you took an image backup of the wordpress installation and the database, and put it in a different VM, and set up the DNS and everything as it needs to be--the new environment looks no different than the old one. All databases, wp-config settings, etc, are the same. So our main website and database functions very similarly.
As I mentioned above, the difference in the protocol stack should be considered. The old system is on PHP 5.6.27--the new one is on 7.3.4. So that could be causing some difference, which maybe somebody might recognize. Wordpress is 5.2.2 and should be compatible with both PHP levels.
We believe there is some relatively simple parameter setting that we are missing. For example, as in the first answer that $table_prefix is set wrongly. But that is not it in this case.
WordPress redirects you to that installation screen because the database it's connecting to is working (meaning, the username and password are correct), but the data it's expecting to be there isn't. Therefore, it assumes it's a new / empty database and prompts you to install WordPress.
I've seen this happen in two scenarios:
The database really is empty, and thus WP needs to install the standard tables and info
The table prefix in your wp-config.php file is incorrect for an existing database
Look at your wp-config.php file in the root directory of WordPress, and look for a line similar to this:
$table_prefix = 'wp_';
Then, open up the database (phpMyAdmin or some other interface to browse what the database structure actually is) and confirm that the table prefixes (the first few characters of the table names) actually match what's set above.
Hopefully this gives you something to go on! Let us know what you find
Migrating Wordpress websites can be quite tricky. I've worked as a WP developer for a number of years and always struggled with manually migrating websites.
There are a number of factors to consider:
WP stores a lot of installation specific information within the database. So you can't do a database dump and upload the export into a new database.
Changing the website url within the wp_options table in the databased there are still other references to the original url scattered throughout the db.
You could try a find and replace all using an editor that supports this sort of functionality (vscode, sublime, atom) but things always end up breaking and your doing tons of "find & replace" actions.
I have always relied on a 3rd party tool Backup Buddy as it simplifies the entire backup and migration process and offers the peace of mind of having easily deployable backups for your website.
Backup Buddy allows you to export your website as a zip and then you can move the zip to any server you want and the plugin provides an installer script (php) to guide you through the migration of your wp site to any host and database of your choosing.
Note: I am not in any way affiliated with iThemes or Backup buddy, and I do not stand to benefit in anyway if you decide to use the plugin. This is only advice on a tool that I have found helpful, reliable, have had success with, and currently actively use on a number of websites that I maintain.
WordPress display installation page because you have not update your wp-config.php file after migrating server so please follow below steps in future when you migrate your website.
Please follow this steps when you migrate your WordPress website from one server to another server.
Back up your website files/database
Export wordpress database.
Create database on your new host server.
Edit the wp-config.php File and edit this details.
Add new database name
Add new database username
Add new database user Password
Add new host as per your hosting provider or (localhost is default)
Import your database to new server.
upload the WordPress files to your new host
defining new domain URL & Search/Replace old domain URL

Installing multiple different instances of wordpress on the same website

I currently have a website up and running that is my freelancing website. What I wanted to do was create a testing subdirectory on the website.
So for example my site would be:
website.com
I want the testing site to be: website.com/test
I need this test to be private and require a password to view, as well as be a different installation of wordpress so I can manipulate it without editing my main website. Is this possible? Currently I have created a test directory from the cPanel that requires a password but it just brings me to a 404 not found page.
I would also like to create more, public, instances that I can use as a portfolio until I get more real clients. So for example I would like to have my site be: website.com/themeOne
Is any of this possible, or am I out of luck? Please let me know I would greatly appreciate any help. Anything I found found online thus far has either not been relevant or has not worked.
You can achieve this by setting up a wordpress multisite installation. I currently use this to host all my clients.
Will work like this.. Main site is website.com
Depending on how long you have had that site set up will determine whether your multisite install will be a subdirectory or a subdomain. If you have had your main site for a while it will be subdomains. ie. xyz.website.com
You will have to set up a wild card subdomain on your server though...so keep that in mind.
Here is the documentation on setting up a wordpress multisite
https://premium.wpmudev.org/blog/ultimate-guide-multisite/
You can install as many WordPress instances as you like in subfolders example.com/test/ or subdomains test.example.com in one hosting account; see http://codex.wordpress.org/Installing_Multiple_Blogs. (You are, of course, limited if your host does not support subdomains. And you may find lots of sites with lots of traffic will slow your whole hosting account.)
For these separate WordPress installs, you can use the same database; simply give each WordPress install a different database table prefix in wp-config.php. https://codex.wordpress.org/Editing_wp-config.php Or, give them all the installs a totally different databases, only limited by your hosting account.
To control access to a WordPress site, there is no need for access control in .htaccess or via Cpanel; use any one of a number of plugins that allow you to restrict access to anyone not logged into WordPress. See https://wordpress.org/plugins/search.php?type=term&q=password
And you can still control the user's role when they are logged into the site with one of those plugins, i.e. editor, administrator, etc., from within WordPress. That's because you want to give a client a Subscriber user level so they can simply login and view the site, rather than Administrator, who can see posts, plugins, etc. See https://codex.wordpress.org/Roles_and_Capabilities
There is no need for WordPress Multisite, unless you want to go that way: see https://codex.wordpress.org/Create_A_Network But be aware that MS requires more server and DNS configurations if you want to use Domain Mapping: https://wordpress.org/plugins/wordpress-mu-domain-mapping/

What step have i missed? Transferring wordpress site

So i have recently tried to transfer my wordpress site to another server.
I have followed a few guides, but i definately seem to be missing a step.
Basically what i have done is:
export original database (phpMyAdmin)
Save all relevant files (ftp)
install fresh wordpress on new server. (wp backend)
'drop' all table fields in new wordpress (phpMyAdmin)
import original database to new location (phpMyAdmin)
transfer theme, plugins, uploads. (ftp)
activate theme, plugins. (wp backend)
update permalinks. (wp backend)
The problem is, i am left with a default looking wordpress installation, and not my orginal page-home.php and corresponding css.
Also, if i go to wordpress backend SETTINGS > READING > Frontpage:static; i only have the option of 'about', not home, i should have 'home'...
Sorry if i am vague, let me know if any screenshots are required.
We really need a little more info like:
when you say plain, do you mean just the theme is not set and you're on the default theme, or there is no theme, or do you mean even your content is not there?
the site you removed it from, where was the installation located? Was is in the public_html folder or a subfolder of that? Did you put it in the same place, ie not inadvertently put it in a different folder
(I've actually typed the bulk of the post and come back to the top for this one, but):
Are you sure you're checking the right site?
Have you kept the same domain name?
Has the domain name propagated to the new server?
Is the CSS being loaded from the correct domain (has anything been hardcoded to the old server)
Let's go through a few broader options:
1. Check how many WordPress installs are on your domain
First off, it sounds like you may have two WordPress installations. If you have the backend setup correctly with your themes but you're seeing a plain site, it sounds like you're looking at another install. I'm not saying you do have multiple installs, but it is a place to start looking.
A question to ask yourself here is: In this plain looking site, do you see your content, or the content of a default site? If you see your content, you may jump ahead to section 2.
If you're saying there is a home page but you're not seeing it as available under static pages, either:
You're looking at another site (but there should be a home page* even in a default setup—from memory), or
You're Home Page title may have changed, or have become "unpublished", ie reverted to a draft, or pending review. Check the page:
actually exists,
has the title you're looking for
the slug hasn't changed
(*note: although it could be a Welcome Page I'm thinking of here.)
Double check the database
The easiest way to do this is to go into your database and see how many WP databases there are. Check each database and look for the underlying table structure, it sounds like you should be able to identify it pretty easily. If it's not a multisite install, the table prefixes should be wp_ unless you changed them somewhere.
While you're playing around in the database, Take note of the database name and table prefix.
Double check the folder structure
Have a look for a second instance of your folder structure, maybe you dropped it into the wrong place).
2. Check the WordPress installation is actually connected to the database
Check the WordPress configuration file wp-config.php is connected to the database. Check wp-config.php sample from codex, you'll want to see the correct database name and table prefix in there.
From here you should also check the username has been setup correctly and is as you expect it. Remember, the database name will likely have a different prefix between hosting providers, unless you've managed to keep the same login name with each provider. ie, I'm talking about the database prefix here, not the table prefix.
(another note: most database connection issues will result in errors appearing on the page in lieu of your site, which leads me to believe it's at least partially setup correctly.)
TEST: What you can do is rename the old wp-config.php to something else and don't create a new one, then visit the website and it will lead you into setting it up again where you can enter the database details (your site info will still be intact, this will only reset your config file, not the database, although it could reset the connection between the filesystem and database).
3. Domain name propagation and DNS settings with your new host
As I mentioned previously, are you checking the right server? Are you sure the domain name has been propagated (if you're using the same domain name that is).
Check the IP address with your DNS provider (for your domain name) is correctly pointed to your new server
Then check that from your command line by typing ping {your-domain-name} and see that your IP address comes up
Check the DNS settings with your web host are setup correctly and that your domain name points to where you want it to point to (ie, public_html or the relevant subdirectory there-of). (This resally does come back to point one, which if you covered it, this shouldn't be an issue
Check that you dropped the files (and all the files) into the correct physical directory, ie public_html (or sub-dir)
If none of these help, please leave a comment with any further developments you've made and as much info as possible, and we can start looking in other areas.
*notes about the database name:
when playing with WordPress directly, ie in the configuration files or the backend administration settings, the database will include your {username}[underscore or hyphen]{database-name}
when playing in phpMyAdmin, they will already be included and you will just provide the {database-name}.
Fellow this steps
export your sql from cpanel---phpmyadmin
make zip of your files in cpanel
import the file in new domain and extract it
create a database link to the new domain
go to new database which you have reacted through phpmyadmin--delete all the tables which was installed by wordpress.
import that sql file which you have downloaded from old website
and in phpmyadmin change the url to new domain name
Regards
Follow these steps:
export database from phpmyadmin.
zip your WordPress project via c-panel.
upload zip file on new domain via c-panel.
extract zip file.
create new database and import old database in new phpmyadmin.
configure user name and password and database name.
change url in database table. from wp_operation table home_url and site_url
Thanks

Removing hard coded site URL from wp-config

After the IP address of my WordPress site had changed,
I had to hard code its address in wp-config.php:
define('WP_HOME','http://54.77.99.66');
define('WP_SITEURL','http://54.77.99.66');
When I delete the lines in wp-config.php, my site is no longer accessible.
How can I get rid of the hard coded entries and set my site's address in the UI (which is currently greyed out)?
I routinely move sites between domains as I test features, restore and test backups, etc. and I always just change the domain throughout the database. The problem with this approach is that many options are store in MySQL as serialized PHP arrays which include the length of a string as a value so you can't just perform a blind search and replace. However, a company called interconnect/it has a free product called Search Replace DB that is able to safely traverse and update these arrays. I say "safely" in that I've run it hundreds of times without issue but they still always recommend backing up your database first.
First download the software above, extract it locally and upload the folder to your server
Using your browser navigate to the folder that you've uploaded
In the search box enter your old site's domain
In the replace box enter your new site's domain
In the database area enter your WP database information
Press the dry run button just to see what the tool thinks should be updated. You'll usually see one or two items in wp_options and a bunch in wp_posts and wp_postmeta. If you have blog wp_comments might get some updates. Depending on your plugins you might get others, too. You can even click the view changes links to see what it thinks it should update.
If this looks good you can hit the live run button and let it perform the updates.
Delete when done. Very important. I'll say it again. Delete when done.
There are some things to be aware of when replacing text. If my site is example.net and my email address is chris#example.net and I perform a replace on just example.net it will change my email address, too. If my site is www.example.net (with the WWW) then I would search on www.example.net which wouldn't catch. I always audit the users just to make there aren't any domain conflicts. If there are, I just perform the above steps a second time, once for each user to change the email addresses back, but this is pretty rare.
The other thing to watch is text-based content about your domain. For instance, if you are keeping your old domain at example.net and spinning off a blog at example.com, the latter might have a blog post about how awesome products are at the former but the replace would point to the latter.
These are the only two edge cases that I've ever run into with this tool, however. Using this tool you should be able to avoid the WP_HOME and WP_SITEURL constants completely.
Also, just in case you are worried, the actual WordPress codex even references and recommends this product.
Changing Your Domain Name and URLs
When your domain name or URLs
change - i.e. from http://example.com/site to http://example.com, or
http://example.com to http://example.net - there are additional
concerns. The files and database can be moved, however references to
the old domain name or location will remain in the database, and that
can cause issues with links or theme display.
...
Use the Search and Replace for WordPress Databases Script to safely change all instances. (If you are a developer, use this option. It is a one step process as opposed to the 15-step procedure below)
This seems to work for me. Honestly not sure how it works:
define('WP_SITEURL', 'http://' . $_SERVER['HTTP_HOST']);
define('WP_HOME', 'http://' . $_SERVER['HTTP_HOST']);
I guess it does 'http://<yoursite>' where <yoursite> is replaced with whatever the address of the server is in your URL bar. Doing this, I can access my site both locally (i.e. via the local IP) and from other networks without issue.

Secure uploaded files in Wordpress

I have site based on Wordpress. Only logged user can see posts, sites, and files (I use s2member plugin).
I have problem with disabling access to files for unlogged user.
I upload files, attach it to post. Only logged user can see post and attachements.
The problem is that unlogged user can download files directly (e.g. http://my-site.pl/files/secret_file.pdf).
How can I prevent this, some plugin, .htaccess?
My site is on shared hosting i have access only via ftp.
There are potential solutions, but none stands out in practice -- each has its own set of thorns.
There are commercial plugins that implement access restriction on part or all of your WP site. Some allow to restrict files, some don't. Amember is one of the more established players in that arena. (I cannot recommend their offer, however. Amongst other problems I ran into, it didn't play well on a multi-server setup.) There probably are some free plugins that do the same since I last checked.
If you decide to code something yourself, there are multitudes of options. Three of them include:
Serving the file using php instead of Apache, and requiring the user to be logged in before serving the file. It works. And it's relatively easy to set up if you decide to be sloppy. It's not so easy if you want to set it up correctly: think partial files that need to be resumed, etc.
Conditionally serving the file using Apache. In essence, you create a user-specific file in a token folder, and you store the name of that file as a cookie when the user log in. Then, have Apache rewrite rules deny access if the corresponding file isn't present in the token folder. This is not easy to set up
Not restricting files at all and leaving things the way they are at the moment: a link to a publicly available file that only members can see. The rational here is that no matter how well you restrict access to your pdf, it'll end up on a torrent site or a download site somewhere if a disgruntled user decides to share it.
Use this in .htacces. this allow user to download or view only .gif, .jpg,.jpeg,.png and .bmp files.
if you don't want to allow this then remove the line "Allow from env=let_me_in"
I hope this will work.
# BEGIN WordPress
<IfModule mod_rewrite.c>
# If the URI is an image then we allow accesses
SetEnvIfNoCase Request_URI "\.(gif|jpe?g|png|bmp)$" let_me_in
Order Deny,Allow
Deny from All
# Allow accesses only if an images was requested
Allow from env=let_me_in
</IfModule>
# END WordPress

Resources