Prevent users bypassing security using web addresses - oracle-apex

After the user has logged in; I have security on page 1 (homepage) of an Apex application which prevents unauthorized users getting any further. Once the user has logged in, it goes away to an apex authorization group and checks whether their name is in the group. If it isn't, it says...you shall not pass.
However if an authorized user copy's the web address of page 3 (view employee salaries), and gives it to an unauthorized user, they can use it, it redirects them to the login page, they login, and there in to that page!
To get round this as a temporary measure i setup each page to have the same authorization group as on page 1. This works but surely there must be a simpler way to manage this?
E.g. User enters the web address, it redirects them to the login page and once they are logged in it doesnt work as they are not part of the group?

I think I found a solution; there is a something called 'Deep Linking' under the security tab in the Application's properties. I have now checked this to disabled and it always redirects the user back to the homepage.

The correct method is indeed to set up authorization schemes on objects that have to be screened off. In apex 4.2 however (I believe - don't think this was in 4.1) you can go to "application properties > security" and there is an "authorization" section there where you can set up a global authorization scheme.

Related

Autotask Postman calls

I am attempting to work with the Autotask Api, would anyone be willing to share some "Postman" Calls to see if i am on the right track?
here is what I have tried.
Post - https://webservices/autotask.net/atservices/1.6/getZoneInfo?
Key -------------- Value
UserName ------------ myApiUserName#email.com
Assuming my credentials are correct (im not sharing here) can you help me to understand why this does not work?
I too am in the early stages of looking into the Autotask API, I can sucessfullly connect to the API from Postman...
You require an API User Account [not a normal user account]
The password for the API Account [obviously]
And a Tracking Indentifier
The API user can be created within Autotask # Admin> features & settings> Resources/users> new Users. You will need to give the new user account the security level API User (System) once you have created the API user account you will need to generate the Tracking Identifier by clicking the Custom [internal intergration] radio button in the bottom right hand corner. Then click the Generate button. Once armed with these three bits of information you will need to goto Postman's Authorization tab and enter the API user credentials. Then goto to the Headers tab and Add the
Key: TrackingIdentifier
Value: <Your Tracking Identifier>
as this has to be included in the header of all GET, POST, DELETE etc. requests.
Finally you will need to be sure you are using the correct url as depending on where your Autotask tenancy is sitting the url will be different. [take a look at your url whilst logged into Autotask].
Hope this is helpful...

Preventing multiple simultaneous logins with Cognito

We have React Native app that uses Cognito for authentication. We would like to prevent the same user ID from logging in simultaneously from multiple devices.
We were hopefully that we could use a Cognito pre-authentication trigger for this. Unfortunately it seems that we can't just call globalSignOut for the user since that wouldn't invalidate tokens that have already been issued and are currently active (see https://github.com/amazon-archives/amazon-cognito-identity-js/issues/21#issuecomment-331472144).
The other idea was to reject the login if the user is logged in elsewhere. But we can't see a reliable way to tell whether the user is already logged in. We can see if there are valid tokens issued for that user but not if they are currently associated with an active session.
We also thought of maintaining our own DB of active sessions but there is no sign-out trigger so we wouldn't know when to remove a session from the DB.
You can use a token authentication system,
Issue a brand new token for each login, and check for available tokens.
if any token is available for the user that means He/She is logged in some other device, for this case you can prompt user that You are logged in other device.. are you sure you want to log out from that device ? and after clicking yes, you can clear all tokens for that user. And issue a brand new token.
AUTO LOGOUT : this token should be passed all over the back-end i.e. in headers of each and every API call token should be there... and should be checked before doing anything in back-end. if token is not available then throw 401. In your app if any API throws 401 then it means user is UNAUTHORIZED and should be logged out.
or
your app should be listening to one socket that responds to log out when it receives a message of same. so whenever your user logs in, a logout message will be passed across sockets and appropriate device with some token id or unique id will get that message and will log out a particular user from all other devices.
or
have a notification receiver which will be used to log out whenever necessary same as socket.
Reading the link you provided the API token / session system seems being faulty by design since long time already.
So without an own token-system inside cognito you won't have reliable results probably, at least in the current state of the system (as the repository is archived it won't be developed further by the owner).
What I propose is an own field in the database-table for users where each login is honored with an own token. A second own field in the same table with a timestamp, where the last access is saved.
If last access is older than a predefined time of 30, 60 or 120 minutes any user gets logged out.
If the last access is younger than the time-limit then the login-mask has to provide a random access token which is compared with that in the database:
- if the access-token in the database is too old for an active session, or just no access-token is stored, then access can be granted which means login is successful.
- the comparison of the current time with the time-stamp saved in the database is for cases where users never have been logged out by purpose but just by being disconnected or passive. I think this case will happen regularly, so it's no exception.
- logging out by click on a button should destroy the access-token in the database, so that the user can immediately login from any device, even from another one then before.
- if there exists a valid access-token in the database then no new access will be granted and the user should get shown a message that he has to sign out first at another login.
- The access-token could be stored together with a third own field for the session-id to make it more reliable and safe. On logout that session-token-field can be cleared too. The session-token can be copied from the global session if required to be saved in the user-record.
- Any checks are only done on login, tokens never have to be included on every page.
- On active logout the token(s) have to be destroyed to allow a direct login again, else the users had to wait till the max. age of the time-limit is reached to login again - at least on another device then before.
As the login itself is currently done independent from the check that has to be implemented, it would be possible to leave the new access-token completely away but use only the session-id as that differs on any device and browser. But perhaps there exists a situation where one of session-id and access-token can change but the other one not - I don't think so but perhaps I missed something in my considerations.
If you provide the access-token on every page like proposed by #Jadeep Galani or in a cookie - beside the corresponding check - you also can offer a button to sign out from all devices. This would enable the users to change login any time even without logging out at the last used device. Without access-token on every page or in a cookie this general logout-function solution is not possible as else access is only checked on login but not on all pages.
A general question is if it's still worth it to rely on the buggy cognito for login or just replace it completely by an own solution. You even could implement the desired authentication in your site in form of a wrapper-class and the concrete login-system could be replaced without changing that implementation.
You can use the UUID of the device to identify whether it is the same user. Add a UUID to each request header to record it in the DB, and then you can do what you want.

Ping Identity switch user

Here at my company, we started using Ping Federate as our Identity provider, this is linked with the AD for user info and so on.
The login works via the OAuth page, and this works great, I can login, do things, then when my access_tokenexpires this get's refreshed and I can continue without the user even noticing it.
But now I got the request of one of the users if he could switch logins.
but this isn't possible, because when I click login, the popup of PingFederate that get's fired doesn't asks for the credentials, it just continues and uses the last credentials.
However when i clean my cookies and I login it asks for the credentials again, but I can't ask the users to clear all it's cookies whenever he wants to switch users.
I tried clearing the cookies of the PingFederate Domain when I logout, but no luck:
me.$cookies.remove('PF', {domain: 'federation.xxx.com'});
any body else has an idea what I can do to make this work?
You should be able to use PingFederate's logout features to achieve what you're after.
If you're using just the HTML Form Adapter to log in users, then you can configure a logout path in your adapter instance that you can ask users to go to to logout. See "Logout Path" here: https://support.pingidentity.com/s/document-item?bundleId=pingfederate-93&topicId=ttq1564003023121.html
Alternatively you could enable single logout (SLO) which will trigger a logout at all adapters or other authentication sources the user may have logged in to. For more details, see:
https://support.pingidentity.com/s/document-item?bundleId=pingfederate-93&topicId=php1564002958041.html
https://support.pingidentity.com/s/document-item?bundleId=pingfederate-93&topicId=pqn1564002990312.html

Automatic cookie single sign on on multiple domains - like google

I don't understand how google achieve the following mechanism of single sign on:
I login in gmail for example (I suppose this creates a cookie withmy authorization)
I open a new tab and direct type the url of "youtube"
Then I enter youtube logged in.
How can this second site detect that I've already been logged in.
They are different domains. Youtube can't read the cookie of Gmail.
All the solutions I've read about Single sign on don't allow this. The client always ask permission to a central login app.
In my example YouTube doesn't know I am the same user logged in Gmail (actually it does know, but I don't understand how)
Note that I type the url of "youtube" by hand. I don't clic the youtube icon from the upper toolbar of gmail (In that case gmail may pass some auth params through the url for example).
The cookies are set on specific domains. Ex:
setcookie(name,value,expire,path,domain)
When you log in on gmail, before "mail.google.com", you have been redirected to "accounts.google.com" then to "mail.google.com" so the cookies are on "accounts.google.com" too.
In this case, the domain is "accounts.google.com" and the path is "/" (the home path).
When you request "www.youtube.com" then you click on "connection" it requests
"accounts.google.com" fast so you can't see this redirection and checks if you have cookies on "accounts.google.com". If so, it checks if the cookies are valid and not expired, or user not banned... Then it redirects you to "www.youtube.com/signin?loginthisSession=Sessionid". This request contains the value of the of sessionid cookie catched from the cookies of "accounts.google.com".
In the last step, "www.youtube.com" logs you and set its own cookie on the domain "www.youtube.com" and saves them.
So the trick is on the 302 HTTP redirect.
Update
i do not know why people keep mentioning iframe take a look at the date whene this questions was posted on 2016 google was not using then iframe as i mentioned the capture of web traffic as you can see SetSID wich means set the cookie of SESSION_ID from accounts.google.dz(com) then redirects to youtube.com it can not be used trought iframe differant domains security measure you can not be redirected from domain to domain trought iframe neither please read this before posting
Cookies and localStorage can be shared between domains using an intermediate domain. On the home page is embedded an "iframe ', which accesses cookies and sends messages to the main.
mail.google.com and youtube.com can share the cookies using accounts.google.es. Open Chrome->Inspect->Resources->Local storage and you will see in accounts.google.com the authentication token in JWT format.
I have detailed the technical steps in this answer: https://stackoverflow.com/a/37565692/6371459. Also take a look at https://github.com/Aralink/ssojwt to see an implementation of a Single Sign On using JWT in a central domain
Check this out.. http://www.codeproject.com/Articles/106439/Single-Sign-On-SSO-for-cross-domain-ASP-NET-applic.
The article consist explanation and sample of SSO cross domain.
As far as I remember, if I am not wrong, cookies contains a specified field that contains the domain that can read and get such cookie. That is made in order to prevent certain web sites to read all your cookie list and make your own business. You should be able to see which kind of sites can 'see' your gmail cookie.
Correct me if I am wrong, this should compile the answer given regarding the SID and gmail-YouTube example..
While evaluating this cross domain SSO topic, I have come up with possible a new SSO synchronization flow using cookie with timestamp. Although it is not a flow used by Google, I think this flow is possible to implement for system with limited number of domains.
This flow do not use 3rd party cookie
This is going to be a long post :)
domains
To make an example, let say we have these domains for our example pet forums:
https://account.domain1.com (For SSO Login)
.domain1.com (e.g. https://cat.domain1.com)
.domain2.com (e.g. https://dog.domain2.com)
.domain3.com (e.g. https://rabbit.domain3.com)
Change to https://account.domain1.com:
Add https://account.domain2.com and https://account.domain3.com, route both host name traffic to the server hosting https://account.domain1.com
Login Steps:
User go to dog.domain2.com, user have not sign in yet.
User click the Login button in dog.domain2.com
User get redirect to account.domain1.com for login
This step can be any Login protocol, OAuth, OIDC, SAML, CAS, etc
So, it is important for user to be redirected back to original page after login
Let say this https://account.domain1.com?redirect_uri=https://dog.domain2.com
redirect_uri as in the URL to go back after login success
User Input username & password, login success
New step, before redirect back to https://dog.domain2.com, set cookies on all domains
Redirect browser to https://accounts.domain2.com?...
Set a cookie on the .domains2.com domain (More on the cookie value later)
Redirect browser to https://accounts.domain2.com?...
Set a cookie on the .domains3.com domain
Redirect browser to https://accounts.domain1.com?...
Set a cookie on the .domains1.com domain
Redirect back to original flow
Redirect user back to their original service, i.e. https://dog.domain2.com
Now, right after login flow we have cookies over all 3 domains. Any of our service (e.g. https://cat.domain1.com / https://dog.domain2.com / https://rabbit.domain2.com ) can access this cookie under their own domain.
Cookie Content
The content of the cookie, should allows for any webpage to look at it, and determine if SSO sync is needed
Different types of cookie content can be stored, including
Boolean indicate user logined or not
User ID
Expired At timestamp
Boolean indicate user logined or not
Storing have_user_login = true / false have sync issue
Suppose User A login, visit https://cat.domain1.com, User A Logout, and User B login
Now, from https://cat.domain1.com standpoint, no sync is needed
However, https://cat.domain1.com is storing User A instead of User B, hence the sync issue.
User ID
While it is tempting to just stored the user_id on those cookie, and let all the domain to see them and set the user accordingly.
This is way too dangerous, since the cookie is set at the parent domain,
if any of the website under your domain been hacked, impersonation might happen (Copying any of the user_id, pasting it to their own browser cookie).
Expired At Timestamp
What I suggest, is for the cookie value to set as the SSO expired time, and set the type as session cookie, this have the following benefits:
An expired time have minimal security impact if leaked / altered
Our website can check the expired time to know if user need to relogin
As for why session cookie, is for when user close them browser, and tried to login again, the cookie will be deleted hence logout the user as well
Any webpage that use the SSO, should also stored a cookie themselves with the same expired time
There will be cases that, User A Login, visit https://cat.domains1.com Then User B Login
Since User A and User B will have a different login expired time, storing and compare that timestamp will tell the user to sync with SSO again
Example checking implement for your service
E.g. On https://cat.domains1.com, you can add this to the top of your page load
<?php
$sso_expired_time = $_COOKIE["sso_expired_time "] ?? 0;
$website_expired_time = $_COOKIE["website_expired_time "] ?? 0;
if( (int) $sso_expired_time < time() || $sso_expired_time !== $website_expired_time ) {
// User not sync, perform sync
setcookie("website_expired_time", $website_expired_time,0,"/", $_SERVER['SERVER_NAME'], true, true);
// Redirect to https://account.domain1.com for Login
// Or, Initiate the login sequence for your selected login protocol
header("Location: https://account.domain1.com/.....")
exit;
}
// User is sync
// Page load success, continue other operation
Logout
Login is very similar to Login, basically:
Before logout goes through, redirect to all 3 domains just like login
Remove the SSO cookie
Continue the normal logout flow
Pro and cons for the methods:
Pro: All domain sync possible
Pro: No need to relies on 3rd party cookie
Cons: First time login longer (around 50ms longer)
Cons: Customization on every website is needed for the sync to works

Django Sessions getting dropped when redirected from another domain

When a user visits my domain, a sessionid is issued by django. When he tries to do Oauth with Facebook, he clicks a button on my site which redirects to Facebook.com. Facebook redirects back to my domain, but at this point, the user's session is lost and Django seems to be issuing a new session variable.
I want the dropped session to persist because I must associate the visitor to my site with his Facebook account, but when the session is dropped, the logged in user is logged out.
I have a suspicion that this may be behavior related to django's XSS protection. How do I make the user information persist when the user leaves our site to log in at Facebook?
You might want to confirm that the cookies have the same domain when being created. That can sometimes cause problems. If you are going to the website www.example.com and the OAuth callback points to example.com, then it's possible you have two separate cookies, one for www.example.com and one for example.com
Turn on "Always Ask" on your browser and pay attention to the cookie details. Make sure that the value for the "Host:" field is the same both times.
The fix is entering something like .example.com for SESSION_COOKIE_DOMAIN in your settings.py file.
I've also just discovered that if you have two Django applications running on the same domain, to avoid cookie collision you may wish to set SESSION_COOKIE_NAME differently for each.