In a security scan result, I received the following error:
"Missing Secure Attribute in Encrypted Session (SSL) Cookie" for WL_PERSISTENT_COOKIE and testcookie.
I don't know how to set the secure attribute for these cookies, from the websphere server it just allows me to set the secure attribute for the JSESSIONID cookie but not for the others.
Here are my conclusions from my appscan results:
testcookie: This cookie seems to be generated in the worklight.js file. According to the appscan, the application sends a request to the server (GET /ParkingApp/apps/services/preview/SmarterParking/common/0/default/worklight/worklight.js HTTP/1.1) and the server responds with this file, which has the following code fragment:
areCookiesEnabled : function() {
var enabled = true;
if (WL.EnvProfile.isEnabled(WL.EPField.WEB)) {
var date = new Date();
date.setTime(date.getTime() + (24 * 60 * 60 * 1000));
document.cookie = "testcookie=oreo; expires=" + date.toGMTString() + "; path=/";
var cookie = getCookie('testcookie');
enabled = (cookie.value === 'oreo');
}
return enabled;
}
So I understand that the cookie is set in this file as the subsequent requests and responses exchange the testcookie.
How can I edit this file as it seems a predefined file in worklight? Would it be a good practice to edit this file so that I modify that line to include the secure attribute?
WL_PERSISTENT_COOKIE: With this cookie I'm a little bit stuck, the worklight server looks for this cookie in the request and in case it is not found it sends it back to the client in a set-cookie header. Actually, this is what I'm seeing in the security scan, however the server doesn't set this cookie to have the secure attribute and I don't find the option in the websphere server settings. How could I set the persistent cookie to have the secure attribute?
Thank you very much in advance!
The short answer is that there is no option to set the secure attribute for either of these cookies. These 2 cookies are not considered sensitive. But AppScan does not know if these are sensitive cookies or not and so just reports that there is no secure attribute set.
In the case of testcookie, it is only used by the client to test whether cookies can be set or not. It is not used by the server at all.
The WL_PERSISTENT_COOKIE is a randomly generated ID to associate a request with a user identity when there is no other user identity established. It is used internally to represent an anonymous ID for purposes like tracking/reporting. It is not used for protecting resources that require authentication and authorization. So capturing a WL_PERSISTENT_COOKIE token and using it from another device or another session would not grant any additional or different privileges.
It seems that both testcookie and WL_PERSISTENT_COOKIE are both used by Worklight.
testcookie is just a fake cookie used to check if cookies are enabled and WL_PERSISTENT_COOKIE is used by persistent cookie authenticator as described in the documentation here:
http://www-01.ibm.com/support/knowledgecenter/SSZH4A_6.2.0/com.ibm.worklight.dev.doc/devref/r_persistent_cookie_authenticato.html
I think you can't change those cookies as they are used/set by Worklight.
Related
When communications happen over http, OpenIdConnect Nonce and Correlation cookies are not removed after successful authentication and it will cause Nginx Request Header Or Cookie Too Large error.
The Microsoft.AspNetCore.Authentication.OpenIdConnect Version=3.1 is used for the web application authentication. After first login, the user will be challenged every time they want to switch between some services. By every re-authentication, two new Nonce and Correlation cookies will be generated. If the communications happen over http, these cookies will not be removed after successful authentication until they got expired (15 mins). If the user keeps switching between services in this period, the app will fail for them withNginx Request Header Or Cookie Too Large error.
For an almost similar issue in Microsoft.Owin.Security.OpenIdConnect, there has been some solutions like this but I couldn't implement it since my app is using AspNetCore OpenIdConnect version 3.1.
How can I implement similar solution in AspNetCore to remove the old nonce/correlation cookies?
It turned out that there was some misconfiguration on OpenIdConnnect options. The problem was that the try to remove cookies was failing because of missing "secure" flag. After setting the SecurePolicy to Always for Nonce and Correlation cookies, they were removed successfully.
...
options.NonceCookie.SecurePolicy = CookieSecurePolicy.Always;
options.CorrelationCookie.SecurePolicy = CookieSecurePolicy.Always;
...
I have a solution for an authentication system without using refresh token. Please tell me where are the vulnerabilities of this method.
I assume the following:
Client and Server are on the same domain.
Client is a browser that support HttpOnly cookie.
Client is using a Single Page Application.
The steps are:
User login by making a request to /api/auth with the credentials.
Server authenticate the user and send back a Set-Cookie Header with an HttpOnly cookie containing a JWT.
Client receive and set the HttpOnly cookie. Client also set in Local Storage a variable logged: true.
After sometime User reopen the browser. The Single Page Application check if the variable logged in Local Storage is == true. If so check if it still has the HttpOnly cookie by making a request to /api/check-cookie.
Server respond with true if it find the HttpOnly cookie and it is valid. Otherwise false.
Client, if receive false from /api/check-cookie, will prompt the user with the login.
With this approach the JWT can have a long expiration date and there is no need to keep track of refresh tokens.
Am I missing something?
I like your thinking and had similar ideas, particularly with setting a local storage variable to reflect the state as logged in so I could check that before making a pointless server call to refresh a token that potentially doesn't exist, however, I'm still using the refresh token.
I believe the crux of your issues will be when the user updates on the server side, it won't be reflected on the client side until the user re-authenticates with a new long-lasting, singular token as opposed to when the short-lived access token refreshes, setting the user again with the updated data.
We use IdentityServer4 in our .NET solution, which also includes AspNetCore Web API and Angular front-end app.
There are standard middleware settings to setup identity like app.UseAuthentication() / app.UseAuthorization() / etc. (it's actually an ABP framework-based solution). As a result of these settings, all authentication tokens (access_token, refresh_token, etc.) are stored in Local Storage (I have not found where exactly I can select between Local Storage and other kinds, BTW).
Anyway, it has worked somehow in our DEV environment.
But suddenly the need to use window.open from Angular app popped up. This page is a Hangfire dashboard. Which accesses other resources related to dashboard functionality. And it caused a lot of headache: now, to identify user in server page called from window.open we need to use cookies (URL is not considered of course).
does it mean we have to switch fully from Local Storage to Cookies for storing tokens?
how and where to set it up? Or, if it's not too wild and senseless to just copy existing access_token to Cookies - when and where to do that? My idea was to copy access_token when it is created in Local Storage to Cookies and delete when a user logs off and probably under bunch of different conditions, like browser window is closed, etc. (which ones exactly?)
probably to set refresh_token to be stored in Cookies and read it in the mentioned server page, then obtain access_token by it (if it makes sense at all)
UPDATE: i've finally came up with the following, but it does not work. The idea is: when Angular app makes request to back-end and authentication token is already present - the token needs to be saved to cookies. I see the cookies is added. But later on - on next request - it falls into the condition again, because actually the given cookie is not saved:
options.Events = new JwtBearerEvents
{
OnTokenValidated = context =>
{
if (context.SecurityToken is JwtSecurityToken accessToken && !context.HttpContext.Request.Cookies.ContainsKey(accessTokenCookieName))
{
context.HttpContext.Response.Cookies.Append(
accessTokenCookieName,
accessToken.RawData,
new CookieOptions
{
Domain = context.HttpContext.Request.Host.Host,
Path = "/",
HttpOnly = true,
SameSite = SameSiteMode.Strict,
Secure = true,
MaxAge = TimeSpan.FromMinutes(60)
});
}
return Task.CompletedTask;
},
...
}
All apps are web application sharing the same domain. And CORS is set up. AllowCredentials() is called as well when setting up middleware.
I have installed "Domino Sample REST Service Feature" from 901v00_11.20141217-1000 version of XPages Extension Library. OpenNtfSample service (com.ibm.domino.services.sample.service.SampleService) works as it should in general and the only problem with it that it completely ignores authentication settings of the server.
I have tried both Basic and Session Authentication as described in Authenticating Domino REST Service Requests and the result I get is the following - the service returns data always and does not ask for any user name and password.
The server is configured with Session Authentication now and I get password prompt when I try to access
{my_server}/api/data
but does not get it when I open
{my_server}/api/sample
After I had added this Web Site Rule
Description: DAS service
Type of rule: Override Session Authentication
Incoming URL pattern: /api/
the server changed password prompt for
{my_server}/api/data
but
{my_server}/api/sample
remained open.
Has anybody experienced this kind of error? Can anybody help me password protect this sample service so that I could start developing my own once based this example?
The /api/sample resource is wide open on purpose. That just returns a link to the contacts resource -- /xpagesext.nsf/api/sample/contacts.
If you really want to prevent anonymous access to the /api/sample resource, there are two possible solutions: 1) Disable anonymous access for all HTTP requests, or 2) Make a change to the RootResource class. The first solution is a server config change. I'm sure you can find details about that elsewhere. Since this is StackOverflow, I'll focus on the second solution.
As you have already noticed, we don't allow anonymous access to the /api/data resource. You can mimic that behavior in the /api/sample resource with a simple change to RootResource.getLinks(). Near the top of the method, just add these lines of code:
boolean authenticated = false;
Session session = ContextInfo.getUserSession();
if ( session != null ) {
String userName = session.getEffectiveUserName();
if ( userName != null && !userName.equals("Anonymous")) {
authenticated = true;
}
}
if ( !authenticated ) {
throw new NoAccessSignal("Need user context");
}
By the way, you won't need to make the same change to the contacts resource class (ContactsListResource.java). Because the contacts resource URL includes a database name (xpagesext.nsf), the web server will attempt to open the database before forwarding the request to the REST service. You can prevent anonymous access to the contacts resource by changing the ACL of xpagesext.nsf. Just make sure the default access is "No access".
I have set up a servicestack service with basic authentication using the first example, here:
https://github.com/ServiceStack/ServiceStack/wiki/Authentication-and-authorization
This automatically sets up a route: /auth/basic
However, I cannot find any information or examples on how to format a request to this URL (Variables/GET/POST/Auth Header, etc.).
I am able to access a simple service using the basic authentication credentials, so they are active and correct.
I have no custom authentication plugged in, just basic authentication.
I have tried:
Using a JsonServiceClient to send UserName and Password variables by GET or Json POST to /auth/basic, with and without an Auth header also containing the user & pass.
Using a browser to send GET requests with URL parameters of the user/pass, or as http://user:pass#localhost:123/auth/basic
I always just get "HTTP/1.1 401 Invalid BasicAuth credentials".
The only examples I can find involve some kind of custom authentication, and then /auth/credentials is accessed, but I want to use /auth/basic
I have looked at the code and it looks like it reads an Auth header, but the service does not accept one.
I am actually trying to get this working so I can then disable it and verify it is disabled (I want to require basic authentication for every request).
Questions are:
What is the correct way to call the /auth/basic service? I will take a servicestack client API example, specifications or even a raw http request!
How do you disable the /auth services altogether?
Many thanks.
What is the correct way to call the /auth/basic service? I will take a servicestack client API example, specifications or even a raw http request!
var client = new JsonServiceClient("http://localhost:56006/api");
var resp = client.Post(new Auth() { UserName = "TestUser", Password = "Password" });
This assumes you have also registered an ICacheClient and IAuthUserRepository (and added a user account)
The JSON format looks like this if you call into /auth/basic?format=json
{
"UserName": "admin",
"Password": "test"
"RememberMe": true
}
How do you disable the /auth services altogether?
Don't add the AuthFeature plugin to configuration.
You can also remove plugins
Plugins.RemoveAll(x => x is AuthFeature);
Putting the following in apphost config seems to do the trick.
//Disable most things, including SOAP support, /auth and /metadata routes
SetConfig(new EndpointHostConfig()
{
EnableFeatures = Feature.Json | Feature.Xml
});
I am a little suspicious about what this does to /auth however, because it returns an empty response, while most routes return 404.
So, would this truly disable the /auth functionality? As in, if someone formed a correct request to /auth/credentials, will it still return an empty response?