In my app I ask users to register using a unique name. The app creates a directory for them with that name that they then can work with, saving files, etc.
I hadn't really thought about screening for other than alpha-numeric for the name. However, I ran across a thread somewhere than said to make sure not to create directory names that match a unix command name.
Is this a legitimate risk? If so, how might one programmatically screen for such an occurrence? I'm also curious how such a scenario might play out to illustrate the problem (exploit?). That last part is academic interest only, of course.
Generally, it doesn't matter(has no obvious security risk). Most softwares, for example shell, search a unix command based on some enviroment variables(like PATH). So even if your created directory matches a unix command like "cd", it can only be used as a parameter to other unix command, like cd cd.
However, if another application search the unix command based on other approaches like searching some directories, it may lead to security breaches.
The only way I can think of that being a risk is if you're going to turn around and process those user names through command-line functions. You would want to be careful to escape the user names anywhere that they could be interpreted as a command...though off the top of my head, with strictly alphanumeric user names, you'd have to go to a lot of trouble to run into such a risk.
If you decided anyway that you wanted to ensure that the username didn't match an application on the path of the creating process, you could shell out from whatever your app environment is, and evaluate the result of which $prospectiveUsername. If it returns anything other than an empty string, you know that the username is an application on the process's path.
NOTE: In the above scenario, make sure you sanitize the username before calling out to the shell command. Otherwise, you do run security risks, if e.g. the user decides to enter her username as "janedoe; rm -rf /".
Related
How can I change the user's password over ssh connection (not via browser interface) on the UBNT (Ubiquity Network) device, more specifically airOS8 WA v8.x board?
I want to avoid the ridiculous restriction imposed by their web interface on the password complexity (the only thing they don't require in the password is the unicorn's blood). I don't feel comfortable with someone else telling me what my passwords should look like (for my own well being, of course), so I'd like to change it via ssh connection, where this restriction is not being imposed.
I followed the discussion on their forums, which is just a useless bike-shedding over the opinions if the developers should impose such restrictions (without the switch to turn that off) or not.
I found the way to do this and wanted to share with others, who need to do the same thing.
First, log in to your device over an ssh connection. Then, issue a passwd command to change your password. If you now just reboot your device, the new password won't be saved, so read on.
Next, you need to copy the new password hash to a file named /var/tmp/system.cfg. So, first, type cat /etc/passwd, to see the new password hash, which should look something like this:
ubnt:$1$ssssssss$hhhhhhhhhhhhhhhhhhhhhh:0:0:Administrator:/etc/persistent:/bin/sh
where ssssssss is the Salt and hhhhhhhhhhhhhhhhhhhhhh is the Hash of the new password. We need to copy all that to the /var/tmp/system.cfg file, so type:
vi /var/tmp/system.cfg and in there, find the line that starts with users.1.password= and change it to be like this (press 'I' for Insert operation):
users.1.password=$1$ssssssss$hhhhhhhhhhhhhhhhhhhhhh
where Salt and Hash will be something randomly generated. When you finish changing that line, press Escape key and then save/quit the file (pressing colon, 'w', 'q' and Enter key, like ':wq')
Once you're back in the shell, type save to save this configuration permanently and then type reboot to check if your password survived the reboot process.
That should be it.
Thanks, but much better is to use a hash of default password ubnt, to get it, just run grep users.1.password /var/etc/default.cfg
Upon deploying a new server and migrating the entire contents of /home using rsync I noticed that the group and user ownership were in fact preserved, despite the fact that the ids differ between the two servers.
Specifically, the command I ran was:
rsync -avz oldserver:/home/ /home
Though I have recreated all of the same users and groups on the new server, most of them have different ids than the old, but somehow this command has magically kept the correct ownership (based on name) and assigned new gid and uid where applicable. I am able to verify this with ls -n /home.
How is this possible? Does rsync do some kind of name lookup?
Yes, by default rsync matches owners and groups by name. Details are in the docs for --numeric-ids.
--numeric-ids
With this option rsync will transfer numeric group and user IDs rather than using user and group names and mapping them at both ends.
By default rsync will use the username and groupname to determine what ownership to give files. The special uid 0 and the special group 0 are never mapped via user/group names even if the --numeric-ids option is not specified.
If a user or group has no name on the source system or it has no match on the destination system, then the numeric ID from the source system is used instead.
rsync presumably uses getpwnam and getgrnam to look up the uid and gid associated with the user and group names.
On a RedHat 6 server, a third party application requires to be root to run and needs access to sqlplus. I have a running database, I can run sqlplus as user 'oracle'. When logged in as user root, 'sqlplus usr/pwd#dbname' works as expected. The trouble is that this agent needs to run sqlplus with no parameters and it always returns ORA-12546: TNS:permission denied.
I've read a dozen times that enabling root to launch Oracle is a security issue but I really have no other choice.
Running Oracle 11.2.0.1.0.
Any help will be much appreciated as I've googled for 2 days with no success.
From the documentation, ORA_12546 is:
ORA-12546: TNS:permission denied
Cause: User has insufficient privileges to perform the requested operation.
Action: Acquire necessary privileges and try again.
Which isn't entirely helpful, but various forum and blog posts (way too many to link to, Googling for the error shows a lot of similar advice) mention permissions on a particular part of the installation, $ORACLE_HOME/bin/oracle, which is a crucial and central part of most of the services.
Normally the permissions on that file would be -rws-r-s--x, with the file owned by oracle:dba, and this error can occur when the word-writable flag - the final x in that pattern - is not set. Anyone in the dba group will still be able to execute it, but those outside will not.
Your listener seems to be fine as you can connect remotely, by specifying #dbname in the connect string. The listener runs as oracle (usually, could be grid with HA, RAC or ASM) so it is in the dba group and can happily hand-off connections to an instance of the oracle executable.
When you connect without going via the listener, you have to be able to execute that file yourself. It appears that root cannot execute it (or possibly some other file, but this is usually the culprit, apparently), which implies the world-writable bit is indeed not set.
As far as I can see you have three options:
set the world-writable bit, with chmod o+x $ORACLE_HOME/bin/oracle; but that opens up the permissions for everyone, and presumably they've been restricted for a reason;
add root to the dba group, via usermod or in the /etc/group; which potentially weakens security as well;
use SQL*Net even when you don't specify #dbname in the connect string, by adding export TWO_TASK=dbname to the root environment.
You said you don't have this problem on another server, and that the file permissions are the same; in which case root might be in the dba group on that box. But I think the third option seems the simplest and safest. There is a fourth option I suppose, to install a separate instant client, but you'd have to set TWO_TASK anyway and go over SQL*Net, and you've already ruled that out.
I won't dwell on whether it's a good idea to run sqlplus (or indeed the application that needs it) as root, but will just mention that you'd could potentially have a script or function called sqlplus that switches to a less privileged account via su to run the real executable, and that might be transparent to the application. Unless you switch to the oracle account though, which is also not a good idea, you'd have the same permission issue and options.
According to the useradd manpage, UIDs below 1000 are typically reserved for system accounts.
I'm developing a service that will run as its own user. I know that well-known ports can be found in /etc/services.
Is there a place where I can find out what well-known UIDs are out there? I would like to avoid crashing with someone else's UID.
getpwent(3) iterates through the password database (usually /etc/passwd, but not necessarily; for example, the system may be in a NIS domain). Any UID known to the system should be represented there.
For demonstration, the following shell fragment and C code both should print all known UIDs on the system.
$ getent passwd | cut -d: -f3
#include <pwd.h>
#include <stdio.h>
int main() {
struct passwd *pw;
while ((pw = getpwent()))
printf("%d\n", pw->pw_uid);
}
UID 0 is always root and conventionally UID 65534 is nobody, but you shouldn't count on that, nor anything else. What UIDs are in use varies by OS, distribution, and even system -- for example, many system services on Gentoo allocate UIDs as they are installed. There is no central database of UIDs in use.
Also, /etc/login.defs defines what "system UIDs" are. On my desktop, it is configured so that UIDs 100-999 are treated as system accounts, and UIDS 1000-60000 are user accounts, but this can easily be changed.
If you are writing a service, I would suggest that the package installation be scripted to allocate a UID as needed, and that your software be configurable to use any UID/username.
I know this is an old post, but since I am here in 2017, still trying to answer a similar question I thought this additional information was relevant for anyone else in the same position.
The concept of "Well known UIDs" stems back to the early days of unix, before there were multitudes of distributions and unix variants. "Well known" UIDs were considered to be those for system users like adm, daemon, lp, sync, operator, news, mail etc, and were standard across all the various systems in order to avoid uid clashes. These users are still present in modern unix-like operating systems.
Standardising uid's across an organisation is the key to avoiding these problems. As was pointed out in a comment above, these days any uid you choose is likely to be in use 'somewhere', so the best a sysadmin can aim for is to ensure that uid's are standard across all the systems that they maintain, then allocating a new uid for an application becomes simple.
To that end, for many years I have found the post linked below invaluable, and sadly there are not a lot of similar posts on the topic, and what's out there is hard to find.
UNIX/Linux: Analyzing user/group UID/GID conflicts
If you search that blog under the 'uid' tag there are other relevant posts, including a script to automate the process of standardising uid's across multiple hosts under Linux.
This User ID Definition is also an invaluable resource.
The short answer is, that it doesn't really matter which uid's you use, as long as they are unique and standard across your organisation, to avoid clashes.
I'm not sure such a list exists. How about just noting that UID's are in use through the /etc/passwd file, /etc/shadow file, and the NIS global user list, noting what ones are in use? Then use one that isn't!
In Linux, that is configured in /etc/login.defs. Sometimes, when I install a Debian-based system, I change the "uid start" option (I forget its name, I'm not on Linux now) from 1000 to 500 for consistency with the other, Red Hat-y machines.
man login.defs should give you all the info you want.
I have a program that is going to take a password as input and then do a shell execute to perform a "su" (switch user) command in UNIX. However, I don't know how to pass the password variable to the UNIX su command. The language I have to use for this is pretty limited (UniBasic).
Any ideas?
Well, the best way to do that would be a setuid-root binary that ask for the password then execute whatever command is needed but it requires knowledge you say not to possess. I'd advise in looking at sudo(1) instead.
You could ssh to localhost as another user to execute whatever command you want. Or, use sudo and edit /etc/sudoers such that sudo does not ask for a password. However, there could be security implications.
EDIT: Please let me know why when you vote it down. My answer may not be perfect but at least it works. I do that myself for some licensed software that can only be run under a weird user name.
You do not want to specify the password as a command-line argument. Not so much because of #unwind's answer (scripts could be made private) but because if someone runs a list of processes, you could see the command argument and hence the password in question.
The version of su I have on my Linux server does not support such an option. I checked sudo, but it doesn't either. They want to do the prompting themselves, to ensure it's done in a safe manner and (I guess) to discourage people from putting passwords verbatim in scripts and so on.
You could also look at the 'expect' utility that was designed to script complex user inputs into a programs that weren't flexible enough to receive this input from places other than stdin.