rspec/rules/S1523/plsql/rule.adoc

76 lines
2.4 KiB
Plaintext
Raw Normal View History

2020-06-30 12:47:33 +02:00
Executing code dynamically is security sensitive. It has led in the past to the following vulnerabilities:
2020-06-30 12:47:33 +02:00
* http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-9807[CVE-2017-9807]
* http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-9802[CVE-2017-9802]
Any code which is dynamically evaluated in your process will have the same permissions as the rest of your code. Thus it is very dangerous to do so with code coming from an untrusted source. https://owasp.org/www-community/attacks/Code_Injection[Injected Code] can either run on the server or in the client (exemple: XSS attack).
2020-06-30 12:47:33 +02:00
2021-02-02 15:02:10 +01:00
2021-01-27 13:42:22 +01:00
``++EXECUTE IMMEDIATE++`` executes as a dynamic SQL statement or anonymous PL/SQL block the string passed as an argument. It's safe only if the argument is composed of constant character string expressions. But if the command string is dynamically built using external parameters, then it is considered very dangerous because executing a random string allows the execution of arbitrary code.
2020-06-30 12:47:33 +02:00
2021-02-02 15:02:10 +01:00
2020-06-30 12:47:33 +02:00
This rule marks for review each occurence of dynamic code execution.
include::../ask-yourself.adoc[]
== Recommended Secure Coding Practices
2021-01-27 13:42:22 +01:00
The best solution is to not run code provided by an untrusted source. If you really need to build a command string using external parameters, you should use ``++EXECUTE IMMEDIATE++`` with bind variables instead.
2020-06-30 12:47:33 +02:00
2021-02-02 15:02:10 +01:00
2020-06-30 12:47:33 +02:00
Do not try to create a blacklist of dangerous code. It is impossible to cover all attacks that way.
== Sensitive Code Example
----
CREATE OR REPLACE PROCEDURE ckpwd (p_user IN VARCHAR2, p_pass IN VARCHAR2)
IS
v_query VARCHAR2(100);
v_output NUMBER;
BEGIN
v_query := q'{SELECT COUNT(*) FROM user_pwd }'
|| q'{WHERE username = '}'
|| p_user
|| q'{' AND password = '}'
|| p_pass
|| q'{'}';
EXECUTE IMMEDIATE v_query
INTO v_output;
END;
----
== Compliant Solution
2022-02-04 17:28:24 +01:00
[source,sql]
2020-06-30 12:47:33 +02:00
----
CREATE OR REPLACE PROCEDURE ckpwd_bind (p_user IN VARCHAR2, p_pass IN VARCHAR2)
IS
v_query VARCHAR2(100);
v_output NUMBER;
BEGIN
v_query :=
q'{SELECT COUNT(*) FROM user_pwd WHERE username = :1 AND password = :2}';
EXECUTE IMMEDIATE v_query
INTO v_output
USING p_user, p_pass;
END;
----
include::../see.adoc[]
ifdef::env-github,rspecator-view[]
'''
== Implementation Specification
(visible only on this page)
include::../message.adoc[]
'''
== Comments And Links
(visible only on this page)
include::../comments-and-links.adoc[]
endif::env-github,rspecator-view[]