Order of intercept-url patterns in Spring Security - spring

In appSecurity.xml I have this:
intercept-url pattern="/users/profile/**" access="hasRole('VIEW_PROFILES')".
intercept-url pattern="/users/profile/edit/**" access="hasRole('EDIT_PROFILES')"
I have a page /users/profiles/edit/addnew and when user with role VIEW_PROFILES is trying to access this page, he gets it successfully but the access to user with role EDIT_PROFILES is blocked.
What I'm doing wrong?

Since "/users/profile/edit/" is more specific than "/users/profile/", it should be placed higher in the list.
Why
Patterns are always evaluated in the order they are defined. Thus it is important that more specific patterns are defined higher in the list than less specific patterns. This is reflected in our example above, where the more specific /secure/super/ pattern appears higher than the less specific /secure/ pattern. If they were reversed, the /secure/ pattern would always match and the /secure/super/ pattern would never be evaluated.
Source: Core Security Filters

Both John Farrelly and Ritesh are correct. The intercept-url patterns are matched in the order listed. As soon as a match is found, the rest of the patterns specified are ignored. This is why you should list more specific patterns earlier.
In your case, the pattern for /users/profile/edit/somepage matches the pattern specified in the first intercept-url pattern, so Spring is appropriately checking to see if the user in question has the access role specified. Apparently, your EDIT_PROFILES users do not have VIEW_PROFILES authority, so they are being denied access. Likewise, your intention to restrict access to ../edit/ to users with EDIT_PROFILES authority is being undermined by the earlier statement which grants access to users with VIEW_PROFILES authority.
Switch the order for the easy fix, and you probably want to give your EDIT_PROFILES users VIEW_PROFILES authority (in addition to EDIT_PROFILES authority). Then, consider using access="hasAnyRole('REQUIRED_ROLE')" rather than access="hasRole('REQUIRED_ROLE')", to simplify the access statements.

Make sure that your EDIT_PROFILES rule is above the VIEW_PROFILES rule. If you take a look at the expression for VIEW_PROFILES, you will see that it includes every URL that would match EDIT_PROFILES. That means that if the VIEW_PROFILES rule is first, spring security will never bother to try the EDIT_PROFILES rule.

Related

Conditional object ACL

New to Parse, coming from Google Firebase, I am not able to completely wrap my head around the security aspect of the platform, let alone write some code. From Firebase, I'm used to writing security rules, by defining conditions that need to be met for certain actions to be allowed (such as: allow write if owner field of post is equal to the current users uid).
So how would I solve following problem? I have an object Post containing properties title, content, owner, public.
Allow reading under following conditions:
if public == true
or currentUser matches field owner
Allow writing if currentUser matches field owner.
Is there a way to implement this? I have found a solution to restrict writing using Cloud Functions, although I am certain there must be a better way.
Thanks in advance!

JSON API REST endpoint with permissions-restricted fields

JSON API REST endpoint with permissions-restricted fields
I am working on a JSON API-compliant REST api. Some endpoints contain fields that should be restricted (read-only or not available) for certain users.
What is the best way to architect the api to allow that certain users have access to certain fields, while others do not? By "best", I mean:
Most compliant with REST standards, ideally JSON API standards
Most clarity in terms of preventing bugs and confusion on behalf of clients consuming the API
I am considering the following options, each with their set of concerns/ questions. I would be more than grateful for any other solutions!
Option 1: Return null on restricted fields for users without permissions
Different data values would be returned per-user. Is this strictly anti-REST?
Lack of distinction between null meaning "null value" and null meaning "You don't have access to this"
In REST/ JSON API architecture, is it okay for an endpoint to return different data per user, based on permissions? I have the impression that this would be contrary to the spirit of resource-based REST architecture, but I could not find anything specific to point to in any doc or standard (e.g. JSON API). Also applies to Option 2.
Is there any paradigm for adding some sort of "You don't have access" flag in the resource's metadata?
Option 2: Exclude restricted fields entirely for users without permissions
Different data values would be returned per-user. Is this strictly anti-REST?
Possibility of "undefined" errors in client, when trying to retrieve field value
Option 3: Move restricted field(s) onto another endpoint, available as an ?include='field_name' relation for those with permission
Example: /api/entity includes attribute field "cost" which is only available to Admin users. Admin users can request cost data via GET /api/entity?include=cost. For all users, "cost" is exposed as a relation in the resource object, with a "type" and "id".
This is the option I am leaning toward. The main con here is endpoint clutter. I have a lot of relations that would need to be made into separate endpoints, simply to support a permissions-quarantined data on an already-existing endpoint.
In the JSON API specs, I am having trouble determining if it's ok for an endpoint to exist as a relation only, e.g. can we have /api/entity/1/cost, but NOT have a top-level api endpoint, /api/cost. My assumption is that if a resource has a "type" (in this case, the relation type being 'cost'), it also has to live on a top-level endpoint.
In this scenario, the client could get a 401: Unauthorized error response if a non-admin user tries to GET /api/entity?include=cost or GET /api/cost/:id
Note: I have already built a separate permissions schema so that the client can determine which CRUD privileges the user has, per top-level endpoint, before making any requests. Permission sets are indexed by resource type.
Any help on the matter would be very much appreciated! And if anything needs to be clarified, feel free to ask.
I would definitely not use undefined or null to indicate fields that the user is not allowed to see. To me, that feels like a lie and represents that the data is really not there. They would have to really know your API in order to get a grasp of what is really going on.
I would recommend something more like your 3rd option, except I would make it a different endpoint altogether. So in your example, the endpoints would be:
/api/entity/1/cost
and for admins
/api/admin/entity/1/cost
or something like that.
This way your server code for the admin endpoint could just be focused on authenticating this admin user and getting them back all the fields that they have visibility on. If a non admin user tries to hit that route, reject them with an unauthorized status code.
I'm not saying that you should not implement the GET param to be able to specify fields as well. You can if you want to, but I don't think it just won't be necessary in this case.

Spring Security 3: hasRole rules are separately checked or?

I have this case in my project:
Imagine we have these two lines to define Spring Security access rules:
<intercept-url pattern="/xxx/*" access="isAuthenticated() and (hasRole('roleA') or hasRole('roleB'))" />
<intercept-url pattern="/xxx/yyy*" access="isAuthenticated() and (hasRole('role1') or hasRole('role2'))" />
These two patterns are nested, and an user may have a combination of roles like "roleA" and "role1", or "roleA" and "role2". What I want to achieve, is make users have "roleC" and "role1" cannot access to /xxx/yyy*.
So my question is:
When user with "roleC" and "role1" wants to get access with pattern "xxx/yyy222.html", will all lines of access rule be checked, or only the second line is checked? When considering the access rules for the second line, can I take it for granted that user can get into the url "xxx/yyy*" have only "roleA" and "roleB", or must I put complete rules for each single lines of rule?
The intercept-urls are processed in the order they are defined, the first with a pattern that matches the request path decides the access.
When user with "roleC" and "role1" wants to get access with pattern
"xxx/yyy222.html", will all lines of access rule be checked, or only
the second line is checked?
This matches the pattern of the first line and access will be denied.
When considering the access rules for the second line, can I take it
for granted that user can get into the url "xxx/yyy*" have only
"roleA" and "roleB", or must I put complete rules for each single
lines of rule?
The second line will never be evaluated. Be sure to specify more specific pattern first.
What I want to achieve, is make users have "roleC" and "role1" cannot
access to /xxx/yyy*.
Maybe you want something like:
<intercept-url pattern="/xxx/yyy*" access="isAuthenticated() and !(hasRole('roleC') and hasRole('role1'))" />

Is it possible to filter statements by Team in Tin Can?

I'm recording statements to the LRS and in each of those statements I always set the "Team" property.
I know I'm able to filter those statements by verb, activity and many other parameters as described here.
However, I can't find a way to filter statements by Team (which is a property of Context).
Is it possible?
I think the best you can do is to use identified groups (a group with an IFI) as the value of the "team" property and then request statements using the "related_agents" query parameter. Note that this will include statements where that identified group is also the "actor" or in any of the other positions accepting a Group/Agent object, so you'll still have to post process them. As far as I know there is no way to request based on an unidentified group since they aren't considered the same group across requests.
There is no way to specifically request only statements based solely on the "context.team" property.
I am assuming that you have added team property to context.extension property. You should not add properties that are not allowed, otherwise, you might have issues in future.
Regarding querying by team or any other extension property, it cannot be done as per standard xAPI Spec. However, your LRS could allow you to do that. e.g. You can get an LRS like GrassBlade LRS or Learning Locker and get it customised to add more filtering options.

Mod Security rules to specific country

How can i make a rule for mod security to only allow specific IP database to access a file name, for example i want to block any IP out of Indonesia IP to accesss register.php
Below is the rule to only block:
SecRule REQUEST_HEADERS:User-Agent "#pmFromFile china_ip.txt" "id:999999,rev:1,severity:2,deny,log,msg:'Block China'"
I'm not a mod-security specialist, but I believe you may use Positive security model to deny access to all requests that doesn't fulfill specific rules.
In your case, you want first to check if the requested URI is register.php, and if the IP is from Indonesia then allow access. I think you may chain the two conditions - it would look something like this:
SecRule REQUEST_URI "GET /.register.php" chain
SecRule REQUEST_HEADERS:User-Agent "#pmFromFile indonesia_ip.txt" "id:999999,nolog,phase:1,allow"
I have no way to test it right now, but I hope this serves as hint of what to to.
Keep in mind though that there is no way to detect proxy-routed accesses, so IP-based blocks may only ward off direct connections.

Resources