Modify rule S2647: Update to LaYC format (APPSEC-970) (#2917)
## Review A dedicated reviewer checked the rule description successfully for: - [ ] logical errors and incorrect information - [ ] information gaps and missing content - [ ] text style and tone - [ ] PR summary and labels follow [the guidelines](https://github.com/SonarSource/rspec/#to-modify-an-existing-rule)
This commit is contained in:
parent
db126ee15c
commit
0aa80c7af2
@ -46,6 +46,7 @@
|
||||
* SQLCipher
|
||||
* Realm
|
||||
* Java Cryptography Extension
|
||||
* Apache HttpClient
|
||||
// JS
|
||||
* Node.js
|
||||
* Express.js
|
||||
|
2
rules/S2647/common/fix/ssl.adoc
Normal file
2
rules/S2647/common/fix/ssl.adoc
Normal file
@ -0,0 +1,2 @@
|
||||
==== SSL encryption for HTTP requests
|
||||
With basic authentication, user credentials are transmitted in plain text, which makes them vulnerable to interception and eavesdropping. However, when HTTPS is employed, the data is encrypted before transmission, making it significantly more difficult for attackers to intercept and decipher the credentials. If no other form of authentication is possible for this code, then every request must be sent over HTTPS to ensure credentials are kept safe.
|
4
rules/S2647/common/fix/token-auth.adoc
Normal file
4
rules/S2647/common/fix/token-auth.adoc
Normal file
@ -0,0 +1,4 @@
|
||||
==== Token-based authentication and OAuth
|
||||
Token-based authentication is a safer alternative than basic authentication. A unique token is generated upon successful authentication and sent to the client, which is then included in subsequent requests. Therefore, it eliminates the need to transmit sensitive credentials with each request. OAuth also works by authenticating users via tokens. It gives even more flexibility on top of this by offering scopes, which limit an application's access to a user's account.
|
||||
|
||||
Additionally, both token-based authentication and OAuth support mechanisms for token expiration, revocation, and refresh. This gives more flexibility than basic authentication, as compromised tokens carry much less risk than a compromised password.
|
0
rules/S2647/common/resources/articles.adoc
Normal file
0
rules/S2647/common/resources/articles.adoc
Normal file
3
rules/S2647/common/resources/docs.adoc
Normal file
3
rules/S2647/common/resources/docs.adoc
Normal file
@ -0,0 +1,3 @@
|
||||
=== Documentation
|
||||
|
||||
* MDN web docs - https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication[HTTP authentication]
|
0
rules/S2647/common/resources/presentations.adoc
Normal file
0
rules/S2647/common/resources/presentations.adoc
Normal file
@ -1,4 +1,4 @@
|
||||
== Resources
|
||||
=== Standards
|
||||
|
||||
* https://owasp.org/Top10/A04_2021-Insecure_Design/[OWASP Top 10 2021 Category A4] - Insecure Design
|
||||
* https://www.owasp.org/www-project-top-ten/2017/A3_2017-Sensitive_Data_Exposure[OWASP Top 10 2017 Category A3] - Sensitive Data Exposure
|
@ -1 +0,0 @@
|
||||
Basic authentication's only means of obfuscation is Base64 encoding. Since Base64 encoding is easily recognized and reversed, it offers only the thinnest veil of protection to your users, and should not be used.
|
8
rules/S2647/impact.adoc
Normal file
8
rules/S2647/impact.adoc
Normal file
@ -0,0 +1,8 @@
|
||||
=== What is the potential impact?
|
||||
Basic authentication transmits passwords in plain text, which makes it vulnerable to interception by attackers.
|
||||
|
||||
==== Session hijacking and man-in-the-middle attack
|
||||
If an attacker gains access to the network traffic, they can easily capture the username and password. Basic authentication does not provide any mechanism to protect against session hijacking attacks. Once a user is authenticated, the session identifier (the username and password) is sent in clear text with each subsequent request. If attackers can intercept one request, they can use it to impersonate the authenticated user, gaining unauthorized access to their account and potentially performing malicious actions.
|
||||
|
||||
==== Brute-force attacks
|
||||
Basic authentication does not have any built-in protection against brute-force attacks. Attackers can repeatedly guess passwords until they find the correct one, especially if weak or commonly used passwords are used. This can lead to unauthorized access to user accounts and potential data breaches.
|
33
rules/S2647/java/how-to-fix-it/apache-httpclient.adoc
Normal file
33
rules/S2647/java/how-to-fix-it/apache-httpclient.adoc
Normal file
@ -0,0 +1,33 @@
|
||||
== How to fix it in Apache HttpClient
|
||||
|
||||
=== Code examples
|
||||
The following code uses basic authentication to send out an HTTP request to a protected endpoint.
|
||||
|
||||
==== Noncompliant code example
|
||||
|
||||
[source,java,diff-id=1,diff-type=noncompliant]
|
||||
----
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
|
||||
String encoded = Base64.getEncoder().encodeToString("login:passwd".getBytes());
|
||||
HttpPost httpPost = new HttpPost("http://api.example.com/foo");
|
||||
httpPost.setHeader("Authorization", "Basic " + encoded); // Noncompliant
|
||||
----
|
||||
|
||||
==== Compliant solution
|
||||
|
||||
[source,java,diff-id=1,diff-type=compliant]
|
||||
----
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
|
||||
// An access token should be retrieved before the HTTP request
|
||||
String accessToken = System.getenv("ACCESS_TOKEN");
|
||||
HttpPost httpPost = new HttpPost("http://api.example.com/foo");
|
||||
httpPost.setHeader("Authorization", "Bearer " + accessToken);
|
||||
----
|
||||
|
||||
=== How does this work?
|
||||
|
||||
include::../../common/fix/token-auth.adoc[]
|
||||
|
||||
include::../../common/fix/ssl.adoc[]
|
33
rules/S2647/java/how-to-fix-it/java-se.adoc
Normal file
33
rules/S2647/java/how-to-fix-it/java-se.adoc
Normal file
@ -0,0 +1,33 @@
|
||||
== How to fix it in Java SE
|
||||
|
||||
=== Code examples
|
||||
The following code uses basic authentication to send out an HTTP request to a protected endpoint.
|
||||
|
||||
==== Noncompliant code example
|
||||
|
||||
[source,java,diff-id=101,diff-type=noncompliant]
|
||||
----
|
||||
String encoded = Base64.getEncoder().encodeToString("login:passwd".getBytes());
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||
conn.setRequestMethod("POST");
|
||||
conn.setDoOutput(true);
|
||||
conn.setRequestProperty("Authorization", "Basic " + encoded); // Noncompliant
|
||||
----
|
||||
|
||||
==== Compliant solution
|
||||
|
||||
[source,java,diff-id=101,diff-type=compliant]
|
||||
----
|
||||
// An access token should be retrieved before the HTTP request
|
||||
String accessToken = System.getenv("ACCESS_TOKEN");
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||
conn.setRequestMethod("POST");
|
||||
conn.setDoOutput(true);
|
||||
conn.setRequestProperty("Authorization", "Bearer " + accessToken);
|
||||
----
|
||||
|
||||
=== How does this work?
|
||||
|
||||
include::../../common/fix/token-auth.adoc[]
|
||||
|
||||
include::../../common/fix/ssl.adoc[]
|
@ -1,27 +1,27 @@
|
||||
include::../summary.adoc[]
|
||||
|
||||
== Why is this an issue?
|
||||
|
||||
include::../description.adoc[]
|
||||
include::../rationale.adoc[]
|
||||
|
||||
=== Noncompliant code example
|
||||
include::../impact.adoc[]
|
||||
|
||||
[source,java]
|
||||
----
|
||||
// Using HttpPost from Apache HttpClient
|
||||
String encoding = Base64Encoder.encode ("login:passwd");
|
||||
org.apache.http.client.methods.HttpPost httppost = new HttpPost(url);
|
||||
httppost.setHeader("Authorization", "Basic " + encoding); // Noncompliant
|
||||
// How to fix it section
|
||||
|
||||
or
|
||||
include::how-to-fix-it/java-se.adoc[]
|
||||
|
||||
// Using HttpURLConnection
|
||||
String encoding = Base64.getEncoder().encodeToString(("login:passwd").getBytes("UTF-8"));
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||
conn.setRequestMethod("POST");
|
||||
conn.setDoOutput(true);
|
||||
conn.setRequestProperty("Authorization", "Basic " + encoding); // Noncompliant
|
||||
----
|
||||
include::how-to-fix-it/apache-httpclient.adoc[]
|
||||
|
||||
== Resources
|
||||
|
||||
include::../common/resources/docs.adoc[]
|
||||
|
||||
include::../common/resources/articles.adoc[]
|
||||
|
||||
include::../common/resources/presentations.adoc[]
|
||||
|
||||
include::../common/resources/standards.adoc[]
|
||||
|
||||
include::../see.adoc[]
|
||||
|
||||
ifdef::env-github,rspecator-view[]
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
"impacts": {
|
||||
"SECURITY": "HIGH"
|
||||
},
|
||||
"attribute": "COMPLETE"
|
||||
"attribute": "TRUSTWORTHY"
|
||||
},
|
||||
"status": "ready",
|
||||
"remediation": {
|
||||
@ -16,12 +16,8 @@
|
||||
"cwe"
|
||||
],
|
||||
"extra": {
|
||||
"replacementRules": [
|
||||
|
||||
],
|
||||
"legacyKeys": [
|
||||
|
||||
]
|
||||
"replacementRules": [],
|
||||
"legacyKeys": []
|
||||
},
|
||||
"defaultSeverity": "Critical",
|
||||
"ruleSpecification": "RSPEC-2647",
|
||||
@ -51,4 +47,4 @@
|
||||
"Sonar way"
|
||||
],
|
||||
"quickfix": "unknown"
|
||||
}
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
{
|
||||
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
== Why is this an issue?
|
||||
|
||||
include::../description.adoc[]
|
||||
|
||||
=== Noncompliant code example
|
||||
|
||||
https://docs.python.org/3/library/urllib.request.html[urllib.request] library:
|
||||
|
||||
[source,python]
|
||||
----
|
||||
import urllib.request
|
||||
|
||||
authenticationHandler = urllib.request.HTTPBasicAuthHandler() # Noncompliant
|
||||
authenticationHandler.add_password(None,
|
||||
'http://www.sonarsource.com/',
|
||||
'sonaruser',
|
||||
'secretpass1!')
|
||||
opener = urllib.request.build_opener(authenticationHandler)
|
||||
urllib.request.install_opener(opener)
|
||||
|
||||
urllib.request.urlopen('http://www.sonarsource.com/credential.html')
|
||||
----
|
||||
https://httplib2.readthedocs.io/en/latest/[httplib2] library:
|
||||
|
||||
[source,python]
|
||||
----
|
||||
import httplib2
|
||||
|
||||
conn = httplib2.Http(".cache")
|
||||
conn.add_credentials('sonaruser', 'secretpass1!')
|
||||
response, content = conn.request("http://www.sonarsource.com/rest/path", "GET") # Noncompliant
|
||||
----
|
||||
https://requests.readthedocs.io/en/master/[requests] library:
|
||||
|
||||
[source,python]
|
||||
----
|
||||
import requests
|
||||
|
||||
conn = requests.get('http://www.sonarsounce.com/rest/path', auth=('sonaruser', 'secretpass1!')) # Noncompliant
|
||||
----
|
||||
https://docs.python.org/3/library/http.client.html[http.client] library:
|
||||
|
||||
[source,python]
|
||||
----
|
||||
from http.client import HTTPConnection
|
||||
from base64 import b64encode
|
||||
|
||||
conn = HTTPConnection('www.sonarsource.com')
|
||||
credential = b64encode(b'sonaruser:secretpass1!').decode('ascii')
|
||||
conn.request('GET', '/', headers={'Authorization': 'Basic %s' % credential}) # Noncompliant
|
||||
----
|
||||
|
||||
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[]
|
9
rules/S2647/rationale.adoc
Normal file
9
rules/S2647/rationale.adoc
Normal file
@ -0,0 +1,9 @@
|
||||
Basic authentication is a simple and widely used method of user authentication for HTTP requests. When a client sends a request to a server that requires authentication, the client includes the username and password (concatenated together and Base64 encoded) in the "Authorization" header of the HTTP request. The server verifies the credentials and grants access if they are valid. Every request sent to the server to a protected endpoint must include these credentials.
|
||||
|
||||
Basic authentication is considered insecure for several reasons:
|
||||
|
||||
* It transmits user credentials in plain text, making them susceptible to interception and eavesdropping.
|
||||
* It relies solely on the server's ability to verify the provided credentials. There is no mechanism for additional security measures like multi-factor authentication or account lockouts after multiple failed login attempts.
|
||||
* It does not provide a way to manage user sessions securely. The client typically includes the credentials in every request, which creates more opportunities for an attacker to steal these credentials.
|
||||
|
||||
These security limitations make basic authentication an insecure choice for authentication or authorization over HTTP.
|
1
rules/S2647/summary.adoc
Normal file
1
rules/S2647/summary.adoc
Normal file
@ -0,0 +1 @@
|
||||
Basic authentication is a vulnerable method of user authentication that should be avoided. It functions by transmitting a Base64 encoded username and password. As Base64 is easy to recognize and reverse, sensitive data may be leaked this way.
|
45
rules/S2647/xml/how-to-fix-it/java-ee.adoc
Normal file
45
rules/S2647/xml/how-to-fix-it/java-ee.adoc
Normal file
@ -0,0 +1,45 @@
|
||||
== How to fix it in Java EE
|
||||
|
||||
=== Code examples
|
||||
The following code uses basic authentication to protect web server endpoints.
|
||||
|
||||
==== Noncompliant code example
|
||||
|
||||
[source,xml,diff-id=201,diff-type=noncompliant]
|
||||
----
|
||||
<!-- web.xml -->
|
||||
<web-app>
|
||||
<login-config>
|
||||
<auth-method>BASIC</auth-method>
|
||||
</login-config>
|
||||
</web-app>
|
||||
----
|
||||
|
||||
==== Compliant solution
|
||||
|
||||
[source,xml,diff-id=201,diff-type=compliant]
|
||||
----
|
||||
<!-- web.xml -->
|
||||
<web-app>
|
||||
<login-config>
|
||||
<auth-method>FORM</auth-method>
|
||||
<form-login-config>
|
||||
<form-login-page>/login.jsp</form-login-page>
|
||||
<form-error-page>/login-error.jsp</form-error-page>
|
||||
</form-login-config>
|
||||
</login-config>
|
||||
</web-app>
|
||||
----
|
||||
|
||||
=== How does this work?
|
||||
|
||||
include::../../common/fix/token-auth.adoc[]
|
||||
|
||||
The Jakarta EE Security API offers robust and standardized methods to handle authentication and authorization in Jakarta EE applications. In the example, form-based authentication is applied to the `web.xml` configuration file. After a user successfully logs into the application, a session is created for the user. A session token is stored in a cookie and is used for subsequent requests.
|
||||
|
||||
==== Integrate with an Identity and Access Management (IAM) System
|
||||
For more advanced authentication and authorization capabilities, consider integrating the backend with an IAM system. Doing so gives access to features like single sign-on (SSO), role-based access control, and centralized user management. As of Jakarta EE 10, support for OpenID Connect (OIDC) is included. Using this authentication method, several OIDC providers can be integrated easily, such as Auth0, Okta, and Azure Active Directory.
|
||||
|
||||
include::../../common/fix/ssl.adoc[]
|
||||
|
||||
In Jakarta EE, HTTPS traffic can be enabled by setting the `transportGuarantee` attribute to `CONFIDENTIAL` in `web.xml`.
|
@ -1,41 +1,24 @@
|
||||
include::../summary.adoc[]
|
||||
|
||||
== Why is this an issue?
|
||||
|
||||
include::../description.adoc[]
|
||||
include::../rationale.adoc[]
|
||||
|
||||
=== Noncompliant code example
|
||||
include::../impact.adoc[]
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
// in web.xml
|
||||
<web-app ...>
|
||||
<!-- ... -->
|
||||
<login-config>
|
||||
<auth-method>BASIC</auth-method>
|
||||
</login-config>
|
||||
</web-app>
|
||||
----
|
||||
// How to fix it section
|
||||
|
||||
=== Exceptions
|
||||
include::how-to-fix-it/java-ee.adoc[]
|
||||
|
||||
The rule will not raise any issue if HTTPS is enabled, on any URL-pattern.
|
||||
== Resources
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<web-app ...>
|
||||
<!-- ... -->
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>HTTPS enabled</web-resource-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</web-resource-collection>
|
||||
<user-data-constraint>
|
||||
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
|
||||
</user-data-constraint>
|
||||
</security-constraint>
|
||||
</web-app>
|
||||
----
|
||||
include::../common/resources/docs.adoc[]
|
||||
|
||||
include::../see.adoc[]
|
||||
include::../common/resources/articles.adoc[]
|
||||
|
||||
include::../common/resources/presentations.adoc[]
|
||||
|
||||
include::../common/resources/standards.adoc[]
|
||||
|
||||
ifdef::env-github,rspecator-view[]
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user