Airomega
Airomega

Reputation: 594

Tapestry 5 URL manipulation

We have a ViewRecordScreen in our Tapestry5 application with a URL:

http://host:8080/app/viewRecord

To view a record from our search screen you simply click a page link. However if you right click the link and select 'Copy link address' you get:

http://host:8080/app/searchresults:viewRecord/12345678

I can now manipulate that url by updating the id to view other records. What is the best way to prevent URL manipulation in Tapestry 5 (I'm assuming I'll have to write some server-side validation code however I'm hoping Tapestry might have a litle something I'm unaware of that could assist.)

Thanks in advance.

Upvotes: 0

Views: 696

Answers (2)

lance-java
lance-java

Reputation: 27994

As with any application, security is the developer's responsibility. You cannot trust a URL and you should always make sure a user is entitled to view / edit an entity rather than blindly letting them do it because the URL said so.

As you are probably aware, Tapestry can automatically convert between clientside strings and serverside objects using ValueEncoders. If you use tapestry-hibernate it will automatically create ValueEncoders for all of your entities. Then, you can use entities as activation context or event context on the serverside and tapestry will generate URL's based on the id's.

If you'd like a to intercept the coercion from string to serverside object, you may want to decorate the ValueEncoderSource with your own custom security checks. This will most likely look up the logged in user from the session.

In my personal opinion, you shouldn't decorate the ValueEncoderSource. You should have services for getting and updating your entities. The services should take a User object as a parameter and should validate before the get / update. The User can be looked up from the session in you pages / components which pass through to the service layer.

eg:

public interface FooService {
    public Foo[] getAllFoos(User user);
    public Result updateFoo(User user, Foo foo);
    public Result createFoo(User user, Foo foo);
}

Upvotes: 2

dinesh707
dinesh707

Reputation: 12592

I think the best way to handle it is to keep track of a user has privilege to do this action. So in the method view record you can check whether the user is logged in or something like that. If not you do not perform the action. You can use session states for keeping track of user state (http://tapestry.apache.org/session-storage.html)

Upvotes: 0

Related Questions