很抱歉,如果重复的话。
假设您有一个Java应用程序,该应用程序的查询可以为以下用户解锁/重置密码:
"ALTER USER " + iD_Of_User.toUpperCase() + " IDENTIFIED BY " + password_Of_User + " ACCOUNT UNLOCK"
iD_Of_User
和password_Of_User
肯定直接来自HTTP请求的地方。
当我尝试使用PreparedStatement对象设置动态值的参数时,会出现错误...我猜PreparedStatement的参数只能用于数据值?而且这里的ALTER查询没有那样使用值。
我认为这里甚至无法进行输入验证-可能在'iD_Of_User'值上,但几乎可以肯定在'password_Of_User'值上(有时用作密码重置-因此,唯一的限制是Oracle 12c密码标准)。
将不胜感激。我查看了此post,但它没有给我一个很好的解决方案。我希望有人知道在Oracle中进行密码重置/帐户解锁的好方法,这不会使应用程序无法进行SQL注入。
使用动态PL / SQL允许绑定变量,并使用DBMS_ASSERT
防止SQL注入。我相信您链接到的问题几乎可以解决。
为了测试,我将PL / SQL块放在another PL / SQL块中。但是在您的Java程序中,您只需要内部块。
begin
execute immediate
q'[
declare
v_username varchar2(128);
v_password varchar2(4000);
v_sql varchar2(32767);
begin
--You may want to catch and handle the exceptions to be more user-friendly.
v_username := dbms_assert.schema_name(upper(trim(:username)));
v_password := dbms_assert.enquote_name(:password);
v_sql := 'alter user '||v_username||' identified by '||v_password;
--Only include this line in debug version, for testing.
dbms_output.put_line(v_sql);
execute immediate v_sql;
end;
]'
--Use bind variables for these values:
using 'test_user', 'passw0rd###1234''';
end;
/