Allowing oracle db login only to specific application? - oracle

We want to allow DB access (Oracle) to our users only through our own application - let's call it "ourTool.exe", installed locally on the users computers. Currently, the users must provide username/password whenever they start "ourTool". The provided password password gets decrypted and we use username/decrypted-password to finally log in to the Oracle DB. This approach prevents the users from directly accessing our DB using third party tools (SQLplus, Excel, Access, ...) and everything in the DB is guaranteed to have been entered/edited using "ourTool".
Now, one of our clients wants to allow its users "single sign-on" (with SmartCards/Oracle PKI). With this, the user will be able connect to our DB without providing any password every time they start "ourTool". But the same will be true for the potentially dangerous tools like SQLplus, Excel, Access, etc.
Is there a way to prevent this? How can we make sure that every record in our DB is only created/edited/deleted using "ourTool" in this scenario?

Since it's your application and you have control of the source, you can use either password protected database roles or Secure Application Roles that are enabled from ourTool.exe. (see http://www.oracle.com/technology/obe/obe10gdb/security/approles/approles.htm ).
For example, with a password-protected database role, the initial connection would be with only the CREATE SESSION privilege, and then ourTool.exe would issue the SET ROLE with password known only to you. Any other application doesn't have the information to set the role. Obviously, the privileges are granted only to the role and not directly to the user in this configuration.

By default, OCI transmits the calling application EXE name and you can access it by querying v$session:
SELECT program
FROM V$SESSION
, which you can do in an AFTER LOGON trigger.
But this can be easily overriden and should not be relied upon.

I renamed my sqlplus.exe to myTool.exe and after making a connection with myTool.exe
SELECT program
FROM V$SESSION
where username = 'SYSTEM';
Returns:
myTool.exe
So be aware, as Quassnoi said: although usable in some circumstances it's certainly not bullit proof.

Related

In Oracle database, can I track logins of different individuals who access the same schema?

My organisation has a number of schemas within an Oracle database that need to be accessed by a number of individual developers. In most cases, the developers can login with their own id and access these other schemas through role permissions, but for certain tasks the individual developers need to log into these schemas directly.
An example of this would be schema A which needs to be accessed by users X and Y. User X and user Y can log in with their own ids, but to fully leverage the potential of schema A, they would need the schema A password.
I am interested in tracking if and when user Y for example logs into schema A, using the schema A password. Can this be done?
My need for this is primarily in relation to password security and leaving procedures when staff depart our organisation. For example, if I have schema A and the password is known by at least some of users X, Y, Z and Q, and user Q leaves, is this a threast? If the checks show the password for schema A was not known by user Q, then I don't have a security risk, but if the checks show that user Q knew the password for schema A, then I need to change the password for schema A, potentially impacting users X, Y and Z.
Therefore, my question is, is there a method within Oracle that would enable me as DBA to identify which individuals logged into these schemas, whether it be by tracking their client identifiers or some other route?
Thanks
For this specific scenario, use proxy authentication: it kills several problems related to development environments in a single stroke.
[Proxy authentication] allows a user to connect to a database as one user and on connection
become a different user. This capability was originally deployed by
Oracle as a way for applications to authenticate end users to
individual database accounts through a common application account, but
it works just as effectively the other way around.
In this model ... each developer is given a separate,
personal account in the database. Most application development can now
be handled – and audited – through these personal accounts. Because
the login accounts are associated with individual users there is no
incentive for the developer to share their credentials with anyone
else. It would be relatively simple to tell if a personal account was
being shared, and doing so would be grounds for termination with most
companies.
To demonstrate this in action, I’ll create an application schema and
configure it so that it can only be accessed by means of proxy
authentication:
Connected to: Oracle Database 19c Enterprise Edition Release
19.0.0.0.0 - Production Version 19.3.0.0.0
SQL> create user app_schema no authentication proxy only connect;
User created.
SQL> grant connect, resource to app_schema;
Grant succeeded.
The “no authentication” option creates the shared
account without credentials. [This is not strictly required, but] it eliminates the need to maintain a
password or certificate for an account that will never be used
directly. The “proxy only connect” option allows only proxy
connections to the shared account. [This too is not required, but could be useful depending on your situation.] The “connect” and “resource” roles
grant basic privileges to use the account and create objects. Next, I
will create a sample development user:
SQL> create user dev_user identified by oracle;
User created.
Now the application schema can be altered to allow
connections from individual developer accounts, like this:
alter user app_owner grant connect through dev_user;
Note the syntax:
the APP_OWNER schema is altered to allow connection by or through the
DEV_USER account. This is not a privilege that is assigned directly to
the development user. Once this proxy privilege has been assigned, the
developer can connect to the application schema using their personal
credentials. All they need do is append the application account name
in brackets to the end of their development account name, like this:
SQL> connect dev_user[app_schema]/oracle
Connected.
SQL> show user;
USER is "APP_SCHEMA"
By connecting in this way, the developer can
still perform needed actions but need never be aware of the
application owner account’s real password (assuming one was even
assigned). The proxy account name (the developer’s personal account)
is available in the system session context, and can be automatically
made visible in the v$session view through a database trigger so that
the DBA can tell who is connected to shared accounts at all times.
CREATE OR REPLACE TRIGGER db_session_trig
AFTER LOGON ON DATABASE
v_proxy_user varchar2;
BEGIN
v_proxy_user := sys_context('userenv','proxy_user');
if v_proxy_user is not null then
dbms_session.set_identifier(v_proxy_user);
end if;
END;
select username, osuser, client_identifier
from v$session where username='APEX_040000';
USERNAME OSUSER CLIENT_IDENTIFIER
----------------- --------------- ----------------------
APEX_040000 oracle PETE
Using the PROXY_USERS view it is easy to
determine exactly which developers have access to each application
owner account as well.
PROXY CLIENT AUTHENTICATION FLAGS
------- -------------- -------------- -----------------------------------
PETE APEX_040000 NO PROXY MAY ACTIVATE ALL CLIENT ROLES
Because even basic auditing
captures the OS username of the developer, the audit trail will record
the actual developer behind DDL operations executed as the application
owner.
Sep 4 10:04:07 testdb Oracle Audit: SESSIONID: "12345" ENTRYID: "1"
STATEMENT: "6" USERID: "APP_SCHEMA" USERHOST: "myserver" TERMINAL:
"pts/2" ACTION: "7" RETURNCODE: "0" OBJ$CREATOR: "APP_SCHEMA"
OBJ$NAME: "TEST_TABLE" SES$TID "4567" OS$USERID: "PETE"
Using
individual developer user accounts with proxy account access to
application schemas, it is possible to allow developers to work in
shared accounts while still maintaining account credential security,
visibility of connected users, and an accurate audit history.
Full article here: https://pmdba.wordpress.com/2021/10/15/shared-application-accounts-revisited/
You could use proxy users for this. That way there is no need to share a password and regular auditing can do its job.
An other option could be to define packages in the other schemas that can be called by the developers. The packages need to be defined with definers rights so when a dev calls the package, the execution is done using the privileges that are directly granted to the schema. Doing so avoids nasty ‘any’ privileges.

DB User account Password Reset from oracle apex

Iam creating an app to change the password of selected Db user account.When an user select a particular db name and user of the db then click submit button i should call procedures that changes the password of the db user.So guide me how to connect to selected db from oracle Apex and do it.
As far as I can tell, there are two ways to change someone's password:
connect as that user
connect as a privileged user (such a SYS)
and run such a command:
alter user scott identified by tiger;
As you'd want to do that for any database you have a access to, as well as every user in those databases, I doubt that you know their passwords so I guess that you'll connect as a privileged user to all those databases. Of course, you have to know their passwords.
One option would be to
create the same stored procedure (which will modify someone's password) in every database
it'll accept username and its new password
as alter table is DDL, you'll have to use dynamic SQL (execute immediate)
create database links to those databases in a schema you use to connect to your Apex application
depending on database you choose, call appropriate procedure via database link and pass chosen username and its new password. This might also require some kind of dynamic SQL, if you want to use different DB link name
I don't know which database version you use, but - have a look at 11g's Accessing and Modifying Information in Multiple Databases, especially "Running a Stored Procedure in a Remote Oracle Database" chapter for more info.

Windows Domain Logins on Oracle SQL Developer

Oracle SQL Developer 4.0.1.14
I currently have an Oracle database with a user who contains a set of tables, views, etc. However, I would like this schema to be shared among multiple people with different logins.
My company has a domain and each employee logs into their computers through this domain, for example
COMPANY_NAME/username
I am hoping to be able to use windows authentication to log each user into the database. This way everyone at the company will automatically have a login with a password they are used to.
In Oracle SQL Developer, I have tried ticking "OS Authentication", and received "Invalid username/password" upon testing the connection. Do I need to create an Oracle user for each domain?
I have also tried checking "Use OCI/Thick driver", but it cannot be checked unless "Use Oracle Client" is configured, which I'm also unsure about.
This question appears to be a duplicate:
Windows Authentication to Oracle for domain group, however the tutorial link is dead. I have not been able to find another tutorial for how to set this up anywhere.
There is a server-side parameter called os_authent_prefix that is typically set to OPS$, and the network user id needs to be prefixed with this in addition to having the IDENTIFIED EXTERNALLY option added to the create user statement.
So if your Windows account id is hambone, then your OS-authentication login would be OPS$hambone, and you don't need a password. I used it for years, and it never required the domain to be specified for a Windows account, which was nice because it meant the same credentials worked for my Unix account.
SQL*Plus, for example would look like:
sqlplus OPS$hambone/#myserver
Likewise, connection strings for applications just have nothing for the password.
For Toad, you would put OPS$hambone as userid and leave the password blank. SQL Developer, I'm honestly not sure -- I can't stand it; I use PL/SQL Developer, but with the various options they have I'd imagine you select OS authentication and/or put the OPS$hambone.
Read the caveats/security warnings on OS authentication. I think in a private network the risks are outweighed by the advantages, but that's for you to decide.

IBM DB2 "Administrator" does not have the privilege to perform "Select"

I've been testing a software I helped develop, which resides on a 32-bit application server. It is to connect to a 64-bit database server, which uses IBM DB2 v10.1.
I was the one to setup the DB2, but I'm pretty sure it has since been modified; I am no longer able to connect using the Username/Password: db2admin/db2admin.
Instead, I have to use Administrator/p#ssw0rd. I do not recall creating that user myself - it is a local account on the computer itself - but from my ODBC tests, it can connect to the database.
However, it appears it doesn't have any privileges. My attempts to see where this 'user' is using Data Studio 3.2.0 have failed, though given my experience (lack thereof) with DB2, this is not surprising.
My concerns are two-fold:
To find where this 'Administrator' resides.
And to modify its privileges to replicate that of db2admin, which, iirc, is a Database Administrator.
My attempts to research the problem on the net was met with failure - either the so called solution doesn't work, or it is too complex for me to understand if it did work (it didn't).
I have tried the following:
Modifying the Database directly via Data Studio 3.2.0; Right clicking on the database, selecting Manage Privileges, and checking everything I could find - note that I did not find any 'Administrator', just a 'PUBLIC', 'DB2ADMIN', 'SYSDEBUG'. Also, it doesn't seem to save.
'Select * from SYSCAT.DBAUTH where GRANTEE = 'Administrator'; This produces a long list of tables, I guess. Don't know what to do with them, but if I replace 'Administrator' with 'db2admin', I get exactly the same result.
Creating a new user called 'Administrator' using Data Studio;
Please, I'd like some light shed on this; DB2 is an extremely frustrating database. I'm using DB2 v10.1, Data Studio 3.2.0, and Windows Server 2008.
DB2 authentication relies on an external mechanism, such as OS security or ldap. If your case, it seems it is Windows security.
DB2 authorisation is internal, so any grant is inside the database, with some exceptions.
There are several authorities in DB2, some at instance level and other at database level. Those at database level, you can find them inside the database, by querying the catalog, and they can be assigned to a user or to a group.
The other authorities, at instance level, are associated to a OS group (external mechanism)
The highest authority in a database is DBADM, and the highest authority at an instance level is SYSADM. Every user in the associated group to SYSAMD becomes automatically DBADM in all database inside the instance.
Well, this is just a short explanation of how DB2 security is. It means that you 'Administrator' user has the 'connect' privilege (sometime 'connect' privilege is public, it means, any user can connect), but it does not have any other privilege, nor authority.
Finally, in Windows environment, there is another security layer, that associates users in two groups DB2ADMNS and DB2USERS. For more information check this link http://publib.boulder.ibm.com/infocenter/db2luw/v10r1/topic/com.ibm.db2.luw.admin.sec.doc/doc/c0023391.html
Well, I solved it, but it remains to be seen why this occurred in the first place;
After creating the user 'Administrator', I modified the privilege by checking everything. It seemed to work.
you have to GRANT a SELECT on the TABLE to the USER.
GRANT SELECT, INSERT ON mytable TO USER peter
"db2 is not frustrating!"

Prevent applications to log in on Oracle Database

Does anybody knows how could I make a trigger or anything else to prevent people to connect on my database with any kind of applications besides mine?
Note that the super-old-and-unsecure trigger to block few .exe such TOAD or watever does NOT really works, since you can just rename the EXE to MyApplication.exe.
Hints?
An easier method would be to move the security to a role that can be enabled only by your application - see a previous answer of mine here
WIth this method another application may create a session but has no other privileges since the role is not enabled.
You may wish to consider Oracle's Secure Application Roles -- it won't prevent people from logging into the database through a rogue application, but it can prevent them from accessing tables and packages if the application doesn't set the role using the password that only it knows.
You can find an tutorial on deploying it here, although to secure it, you'd have to create the role with a password, and your application would have to know the password when issuing the SET ROLE rolename IDENTIFIED BY rolepassword; statement.
I don't know that Oracle has any functionality to help with this (I could be wrong though) so the next best thing might be to write a small server app that lets you have much better control over the login process and acts as the middle-man between the client apps and the database server. That way, all connections to the database come through your server app, and you can control how your server identifies which client app is legit. This will add a bit of complexity to the system though.
If you don't trust the program name in v$session then the only options that come to mind are to have your application encode the password, so that what they type in isn't actually what's used to connect to the DB; or have your app log in with a private username/password and authenticate users against your own users table instead of having Oracle user accounts for them. Both options make management of accounts more complicated though.
When your application logs on, you call a stored procedure that associates the current oracle session as a "trusted" session. Do this by creating a trusted sessions table with a field for sessionID and trusted bit (and optionally a random hash to prevent user tampering).
Create a system wide trigger, that checks the your current session id (and random hash) to detect if it is trusted. If the session doesn't exist in the table, you don't allow the query, and log off the user.
You should also setup a shutdown trigger to clear the trusted session table on exit.

Resources