How to send Session ID parameter out FROM Moodle? - moodle

I need to send user-specific values to an external system from Moodle. How can I force Moodle to send the session ID (or user ID, activity ID, etc.) to this third-party system? All of the articles out there seem to be written for calling into Moodle but this is not what I need to do.
Important:
I cannot alter the Moodle installation. The solution must only involve editing content. This means I cannot author a new plugin or alter any of the Moodle source code.
Edit:
I do have direct access to the Moodle database from a separate external API. The goal was to use this connection to validate the incoming parameters. However, I still need to be able to construct a parameterized URL to call out the external app. That app would then be able to validate the supplied values against the database. If the session ID is not available then I would need the values regarding the page, user, module, etc. to be sent via the parameterized URL.

For the session id do you mean the current user session? There is a session key stored in $_SESSION['USER']->sesskey but its not really useful data. It expires when a user logs out.
$_SESSION is server side, so you would need to use PHP code which isn't allowed in content for security reasons.
Have you got access to the database? You could pull user id and activity id from there. Otherwise you will need to use an API or a plugin.
EDIT: There is a URL activity that you could use to send data externally. But that would require the user to click the link.
Data includes user and course ids.
https://docs.moodle.org/311/en/URL_resource_settings
I can't think of any solution to send data externally without writing some PHP code or adding a plugin.
You can add javascript to every page via Site administration > Appearance > Additional HTML but the session variables aren't available without PHP.
https://docs.moodle.org/311/en/Header_and_footer

Related

What is the best approach to stop your platform's users to "sniff" the frontend requests to backend and modify them?

So I have a platform that works like this: Users can create accounts by logging in with their Google (I USE AUTH0) and then they can create "Projects" which contain lots of other unimportant stuff regarding my current problem (like todo lists, ability to upload files etc; they can also Edit the project by changing some of it's attributes like name, description, theme and so on). There is a home page where everyone can see each other's projects and access them (but not upload files, change the tasks in the to do lists; this is possible only by the person that owns it).
By using a tool like Burp, people can see the request made from frontend to backend, for example when accessing one of the projects, and modify it on the fly.
This is what it looks like inside Burp when they access one of the projects:
As you can see there is a Get request to /projects/idOfTheProject; they can replace the GET with DELETE for example and they will successfully delete it; they can also see what is sent to the backend when a project is edited (name changed, description, thumbnail picture etc) and change anything they want about it.
How should I prevent this?
What I've looked at so far:
a. JWT - Probably the best fitting for my situation, but required the most work to be done (as I already have my platform almost finished with no such a security measure implemented yet, so I may need to rewrite a lot of things in both backend and frontend)
b. Sending the user's id that initiated the action as well to the backend and verify if it has the necessary privileges - the worst solution as users can access each other's profile and see the id, then just change another field in the request's JSON
c. Have a sort of token for each user and send that instead of the user's id - in this way somebody can't get your token by just looking at the communication between frontend and backend (only if it is using YOUR account). That token should be taken maybe somewhere from the auth0 when they create their account? If they provide something like that; or I can just create it myself and store it alongside the other user variables. You would still see the requests in plain text but even if you modified something you would still have to "guess" the owner's token, which will be impossible.
For frontend I use NextJS and for backend Flask.
Thank you in advance!
The TL;DR is that you don’t. A determined user will always be able to see what requests are being sent out by the code running on their computer and over their network. What you are describing when asking how to prevent people from “sniffing” these requests is security through obscurity, which isn’t actually secure at all.
What you should do instead is have an authorization system on your backend which will check if the current user can perform a given action on a given resource. For example, verifying that a user is an administrator before allowing them to delete a blog post, or making sure that the current user is on the same account as another user before allowing the current user to see details about the other user.

specify user id when creating user in keycloak

I'm investigating a migration process from a legacy system into keycloak. Based on some of the ideas here: https://github.com/Smartling/keycloak-user-migration-provider we're looking to create user accounts in keycloak at the point of login by looking up user credentials from some dedicated endpoints on our legacy system.
As part of this, I need the user ID to remain the same as it was in the legacy system.
Is it possible to create a user with a specified ID rather than relying on keycloak to auto-generate it?
Running into this issue when attempting to create users via the API, I looked into the code for the users service. It looks like it is currently not possible to set the user id due to how the user is created.
From the code in https://github.com/keycloak/keycloak/blob/master/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java specifically on line https://github.com/keycloak/keycloak/blob/7cfe6addf01676939206e034a87c791460031032/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java#L115 the user is first created using the username, then updated. I believe id is not an updatable field. Thus it is not currently possible.
Checking the api I see it is now possible to add an optional "id" field in the userRepresentation object that you pass to create a new user in keycloak.
Find more information here: https://www.keycloak.org/docs-api/5.0/rest-api/index.html#_userrepresentation

How facebook knows all user connections so fast?

I'm developing a service, that uses social graph.
There is a separate module, that manages user connections, that is basically responsible for all related operations. In some services, you need to know all user connections, to provide correct responses.
The way I see it there are 4 possible options to implement this:
Server based connection support.
1.1. Each time social graph data requested ask for friend list from the module, and process corresponding response.
1.2. Have internal cache with Key - playerID, Value - all player connections, add responsibility to update this cache to connection module, and use it instead of referring to this module.
Client based connection support.
2.1. Add a special Cookie with the list of all friends, so that server could just read that Cookie and provide needed information, without talking to the external module. (This can be secured, by for example providing some signature for the Cookie, and optimised by adding some path, for all the connections related data)
2.2. Add a connection management layer in Client, so it would explicitly request all needed information, by providing a list of connections on each request.
As I look at facebook Cookies, there is a fr cookie, which I can speculate used for this kind of functionality.
How facebook solves this?
If you just want to maintain a list of friends for each user you don't need a full social graph. A simple list of friends stored in your database would work fine.
Client-side storage is typically only for caching or session data, you don't want your users losing their friend list because they re-installed their browser or switched computers.
If you do want to implement a full social graph have a look for a graph DB. Neo4J is one I've used and is fairly easy to get started on.

Authenticating calls from Phonegap app to REST server

I'm building an app with Phonegap. It simply reads xml feeds to display latest articles uploaded by a school for parents to read.
There will be an option where each user of the app can decide whether they want to receive Push Notifications or not. I have a simple database table where the device's registration i.d. from Google Cloud Console is stored. When the user clicks "yes", the registration i.d. is generated and stored on the server. If they then click "no", it's deleted. I want to secure these call to the server with basic HTTP authentification.
Any documentation I have seen on basic authentification describes the sending of username and passwords. But with my application, there is no username or password as the users do not need to sign up. What do I send to authenticate the client? Would there be a key hard-coded on the client side and sent with each request? Couln't this be easily exposed by unpacking the .apk?
I object to the premise of the question. I actually see this as less a security issue and more a preferences issue. Understanding the distinction makes the development of your feature much easier.
Simply modify your application to allow the user to configure what he or she wants to see in the settings and then store the preferences wherever you want on the client (like local storage). The server can then push as before, but the app should simply refuse to render those pushes that the user doesn't want to see.
If you want to simply disseminate non-sensitive content to the users who want to see it, this is a preferences issue and/or a publish/subscribe issue. But it is not a security issue.
Since you have access to server side, you have the control of the whole process. So, in order to handle that, you may think about something like session cookies that a web server creates in case of normal authentication.
I have done something similar and what I've done is to generate a kind of token server side that is stored in the cookies of the device or the localStorage.
So the process flow should be something like this :
Generate a token and store it on the device (cookies or local storage).
For each request, send this value in a http header
From server side, you may identify the user from that token.
For example : you maintain a table that identifies device/token.
That's it
In addition to what the other answers said you can pass a custom useragent string as part of the requests, and validate it matches what you expect. It's not a sure way to 'secure' requests, but along with a (simple) token system and HTTPS this could be enough for your needs.

Adobe CQ5: SSO without LDAP?

A customer of ours has just purchased CQ5 and would like to externalize all of its security. We'd like to use an STS server for SSO and then leverage a custom authorization/attribute provider instead of the CQ5 repository. Ultimately, we do not want to use LDAP in any way.
Here is how we envision this (some pieces already working):
User browses to CQ5 Dispatcher running in Apache
Apache filter redirects user to STS site where login is completed.
User is redirected back to Apache with SAML Claims.
User ID token is placed as cookie into browser. (everything is working up to here)
CQ5 captures that cookie based on the SSO configuration (working)
Problem starts here: From here, we want to call a custom authorization provider for the user's attributes, roles, groups etc...
We have tried to figure out how to do this and can't seem to find the missing link.
Do we need to create a custom login module? Do we need to create a custom principal provider? Do we somehow use the existing LDAP capability in CQ5 but have it call a custom class which leverages the external auth source?
If anyone here has any idea how to do this, their karma quotient would be full for the year if they could share it. I'm not sure if this is a basic thing you do with JAAS or even where to put my classes after I've created them.
We've worked really hard on this so far and seem to be close, but we keep hitting dead-ends.
Thanks so much if you have an idea where to begin!!
-joe
Recent versions of AEM now include the SAMLAuthenticationHandler which allows you to:
Redirect users to SSO to simulate IDP initiated login, or
Allow AEM to perform SP initiated login with IDP
Specify attributes to take from the SAML Assertion and add to the user's profile node (not sure if you can use this for groups)
Specify which groups users should be added to
Set a cookie called request-path that will store the URL the user arrived at, and then redirect them to that location when they're authenticated (ie. deep linking)
This makes relying on the SAMLAuthenticationHandler better than using Apache to redirect. The current version of the handler bundled with AEM 6.2 does not properly set the cookie when using the redirect method, but Adobe does have an updated version that they can provide that will fix that problem.
I normally recommend that clients do not have their own authentication handlers developed inside AEM.
When not using LDAP, this does create an issue where users will not exist until they've logged in. Additionally, when your architecture includes more than one load balanced publisher, it is possible that a user may exist on one server user synchronization.
Try searching the google group for SSO details. Here's one useful post:
http://groups.google.com/group/day-communique/browse_thread/thread/72c235c83a501252/fba4d08a90487156?lnk=gst&q=SSO#fba4d08a90487156
It seems that you will have to implement a custom LoginModule, more information here: http://dev.day.com/docs/en/crx/current/deploying/custom-login-modules.html