Where is result of OBJECT_NAME(##PROCID) obtained from? (typo corrected) - sql-server

I have a stored procedure that has EXECUTE AS another user that has very restricted access. I cannot get the results from OBJECT_NAME(##PROCID) when I run that stored procedure. ##PROCID does have a value, so it's the lookup that is failing.
I think it's a permissions issue, so can someone tell me where the name of the stored procedure is obtained from? Maybe I can fix my issue by granting some SELECT permissions to the EXECUTE AS user.
If anyone has any other ideas, LMK. I'm hardcoding the stored procedure name for now.

From the documentation for OBJECT_ID:
A user can only view the metadata of securables that the user owns or on which the user has been granted permission. This means that metadata-emitting, built-in functions such as OBJECT_ID may return NULL if the user does not have any permission on the object.
Also further reading will also tell you that you need to grant the user any permission on the object (i.e. SELECT, EXECUTE etc.)

Related

Stored procedure does not have SELECT permission [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 days ago.
Improve this question
If on SQL Server, only the user is given the EXECUTE permission, it is reasonable to say that as long as the query SP is executed, even if the permission is not given, it should be able to execute it. Why does it say that there is no select permission when executing the query SP, such as adding and modifying? , The deleted SP can be executed normally, and the user is not given insert, update, delete permissions
DB: shop_sample
SP: member_search
User: TEST
Database role: db_denydatawriter
Restrictions:
Do not use EXECUTE AS
Do not create another SCHEMA
The user only has the SP execute authority, and has no insert, update, delete, select authority
Specific database shop_sample can execute SP
When I set
The following message will be reported:
Schema description 'dbo', database 'Shop_sample', object 'role.memberdata' does not have SELECT permission
When using a different query SP,
One is select * from table
One is with parameters,
Why do those with parameters say that there is no select permission, but those without parameters can be executed normally?
If I use grant select but it still fails
Grant select on [dbo].[member_search] to [TEST];
GO
Granted or revoked permission SELECT is incompatible with object
Thank you very much for your assistance. Thank you in advance
Can someone tell me how to set user auth in SSMS?
First, you cannot give select permission on a procedure. Instead, you can give select permissions to one specific table (or, well, all of them).
Now to clarify you thoughts about "if you have execute on a procedure, it should run". It usually seems like that, but is actually more complicated. As the excellent article by Erland Sommarskog indicates, this happens only when the procedure owner and the table owner is the same. In many cases, the owner is just [dbo], and it all works. But it might not be so in your case.
To complicate things further, even if the owner of the proc and table are the same, if you use dynamic SQL, this is instantiated as a nameless procedure with no owner, which will fail the comparison and force object-level checks for each table. In that case, you will have to have the procedure signed.

How do I cancel all queries for a particular user in Snowflake?

I know that, in the docs, it says I can cancel all queries from a session with this command
SELECT SYSTEM$CANCEL_ALL_QUERIES(<session id>)
What's the equivalent for canceling all queries from a particular user? I have a user where every query comes from a different session ID and I'd like an easy way to abort the queries from this user. I'm referring to a Snowflake database
rather non-obviously, you need an ALTER USER statement:
ALTER USER [ IF EXISTS ] < name > ABORT ALL QUERIES
Permissions to be able to run this:
GRANT CREATE USER ON ACCOUNT TO <role>

grant a user to execute only one stored procedure but can't run other queries

Is it possible to grant a user execution on a stored procedure but prevent him of running other queries even if he typed the exact same stored procedure?
Basically what I'm trying to achieve here is to prevent a user to see all rows in a view(select all from View1), but he can select only one row with 'where' condition by a stored procedure.
Yes, it is possible, simply take away all the permissions of that user and grant the user only execute permission on a single procedure.
GRANT EXECUTE ON dbo.ProcedureName TO [UserName];
or
GRANT EXECUTE ON OBJECT::dbo.ProcedureName TO [UserName];
Why not create a view for that user that is limited to only the data that particular user has access to? No need to have a stored procedure for simply accessing a row of data.
By using a limited view, the user can choose to incorporate that view record into a query as a JOIN, or write their own stored procedure/function as they see fit. A view would be a more flexible way to do what you are attempting.

mssql Stored Procedure permissions problem

I am testing the permissions in mssql and run into a problem. I've made a 'Countries' table and a 'spCountries' Stored procedure. Now I've made a user 'silverlight' and gave it no rights to the Countries table. The user can execute the stored procedure.
Now when I do a Select it fails like it should, but in a exec spCountries, al the data is visible. How can I check for the permissions in the stored procedure?
Is this also possible if the stored procedure does EXEC "SELECT * FROM Countries" instead of just SELECT FROM ...?
Maybe it's also better just to return an empty recordset instead of an error...
Does somebody have an idea?
SELECT has_perms_by_name('dbo.Countries', 'OBJECT', 'SELECT')
That's due to ownership chaining. Basically, if the same principal (e.g. dbo) owns an SP and a table used int it, permissions for the table are not checked.
Actually, this makes sense. For instance, it allows you to give a user acces to some data, but only in specifiŅ ways coded in the SPs.
If you use dynamic SQL, the permissions are calculated every time. Since SQL2005 you can use EXECUTE AS clause to specify execution context. For example, EXECUTE AS OWNER makes dynamic SQL in the SP execute in SP owner's context, giving similar effect to ownership chaining with static SQL.
That is how permissions work in SQL Server.
So you can give permissions on stored procedures without having to give permissions to the underlying objects. This allows you to exercise control over exactly what updates etc. people can make.
Don't give the user silverlight permissions to execute the stored procedure if you don't want them to execute it!
Edit: Although having read the question again it sounds like maybe this is the kind of thing you need?

If my database user is read only, why do I need to worry about sql injection?

Can they (malicious users) describe tables and get vital information? What about if I lock down the user to specific tables? I'm not saying I want sql injection, but I wonder about old code we have that is susceptible but the db user is locked down. Thank you.
EDIT: I understand what you are saying but if I have no response.write for the other data, how can they see it. The bringing to crawl and dos make sense, so do the others but how would they actually see the data?
Someone could inject SQL to cause an authorization check to return the equivalent of true instead of false to get access to things that should be off-limits.
Or they could inject a join of a catalog table to itself 20 or 30 times to bring database performance to a crawl.
Or they could call a stored procedure that runs as a different database user that does modify data.
'); SELECT * FROM Users
Yes, you should lock them down to only the data (tables/views) they should actually be able to see, especially if it's publicly facing.
Only if you don't mind arbitrary users reading the entire database. For example, here's a simple, injectable login sequence:
select * from UserTable where userID = 'txtUserName.Text' and password = 'txtPassword.Text'
if(RowCount > 0) {
// Logged in
}
I just have to log in with any username and password ' or 1 = 1 to log in as that user.
Be very careful. I am assuming that you have removed drop table, alter table, create table, and truncate table, right?
Basically, with good SQL Injection, you should be able to change anything that is dependent on the database. This could be authorization, permissions, access to external systems, ...
Do you ever write data to disk that was retrieved from the database? In that case, they could upload an executable like perl and a perl file and then execute them to gain better access to your box.
You can also determine what the data is by leveraging a situation where a specific return value is expected. I.e. if the SQL returns true, execution continues, if not, execution stops. Then, you can use a binary search in your SQL. select count(*) where user_password > 'H'; If the count is > 0 it continues. Now, you can find the exact plain text password without requiring it to ever be printed on the screen.
Also, if your application is not hardened against SQL errors, there might be a case where they can inject an error in the SQL or in the SQL of the result and have the result display on the screen during the error handler. The first SQL statement collects a nice list of usernames and passwords. The second statement tries to leverage them in a SQL condition for which they are not appropriate. If the SQL statement is displayed in this error condition, ...
Jacob
I read this question and answers because I was in the process of creating a SQL tutorial website with a readonly user that would allow end users to run any SQL.
Obviously this is risky and I made several mistakes. Here is what I learnt in the first 24 hours (yes most of this is covered by other answers but this information is more actionable).
Do not allow access to your user table or system tables:
Postgres:
REVOKE ALL ON SCHEMA PG_CATALOG, PUBLIC, INFORMATION_SCHEMA FROM PUBLIC
Ensure your readonly user only has access to the tables you need in
the schema you want:
Postgres:
GRANT USAGE ON SCHEMA X TO READ_ONLY_USER;
GRANT SELECT ON ALL TABLES IN SCHEMA X TO READ_ONLY_USER
Configure your database to drop long running queries
Postgres:
Set statement_timeout in the PG config file
/etc/postgresql/(version)/main/postgresql.conf
Consider putting the sensitive information inside its own Schema
Postgres:
GRANT USAGE ON SCHEMA MY_SCHEMA TO READ_ONLY_USER;
GRANT SELECT ON ALL TABLES IN SCHEMA MY_SCHEMA TO READ_ONLY_USER;
ALTER USER READ_ONLY_USER SET SEARCH_PATH TO MY_SCHEMA;
Take care to lock down any stored procedures and ensure they can not be run by the read only user
Edit: Note by completely removing access to system tables you no longer allow the user to make calls like cast(). So you may want to run this again to allow access:
GRANT USAGE ON SCHEMA PG_CATALOG to READ_ONLY_USER;
Yes, continue to worry about SQL injection. Malicious SQL statements are not just about writes.
Imagine as well if there were Linked Servers or the query was written to access cross-db resources. i.e.
SELECT * from someServer.somePayrollDB.dbo.EmployeeSalary;
There was an Oracle bug that allowed you to crash the instance by calling a public (but undocumented) method with bad parameters.

Resources