For a long time in 7 vision, we used client tags to store state within our app. We want to do the same in 8 perspective. In 7, we would write to these state tags with scripting or bindings and many of our Templates would refresh data based on those changes. We felt pretty confident trusting those tags as how would someone modify them without going through our UI, which used various security controls.
We thought the session would be safe to use in the same way in 8 perspective. All was going well until we had more than one window open and realized the session was shared across windows. So, changing state in one window would change it in the other. To solve this we moved most of our state props to the page level in a custom map.
My question is, can we trust these page level props to only be changed by our scripting and messaging on views? I'm not sure if these props are managed similarly to the session or if they are handled all in the frontend. I'm concerned there might be a way for a bad actor to access and change these properties manually. For example, to look at data they typically wouldn't be allowed to. I'm wondering if we should treat all the event scripts and bindings refreshing data as a traditional web backend, and double check the user has access to the data they are requesting.
If you right click the properties, you should have an option to set the access level. Public is sent to the client and can be adjusted externally (dev console), protected is sent to the client and cannot be edited externally, and private is not sent to the client.
That makes sense, I think we'd only do this with our custom props.
This is perfect for session props and component props. But, the page.props.custom we read/write to doesn't exist in the designer so I'm not immediately sure how to set the access level for those. Same with props added dynamically to the session. Some testing to do for sure.
Do you know of anywhere in the docs that shows how to read/write those props from the browser console so I can test my changes are working?
Unfortunately not aware of any, though it will probably vary a little based on the browser. I don't ever touch data via the dev console. Maybe someone more savvy will weigh in here.
I'm not aware of any way to do this on demand. Might have to have a dummy property that is set to private and then load everything into that.
Yeah, i'm leaning that we will need to move everything back to the session mapped by page. Have a higher level prop like "pages" and make sure that has the right access level. Thanks for the help
Perspective session properties, are from a scripting point of view, exactly the same for Perspective as Client Tags are for Vision. Bindable and readable and writable across the entire client (browser tabs and all inner views in Perspective, all windows/templates in Vision).
Perspective doesn't expose any mechanism to manage page.props. That you can create new keys there via script is essentially accidental. It is not a documented/supported feature, and might break entirely in the future. You cannot make bindings that write to them.
Consider using the pageVarMap() functions from my Integration Toolkit to track per-page values, and pull them into your various views.
Another point to consider:
session custom properties might seem a convenient place to put things, but be very careful not to make a mess. It's hard to figure out what can write to these props, and where they're used, so it can quickly become a maintenance nightmare.
Does anyone know if setting the access to private on an object type session custom property protects all children of that object?
Poking around with the __client object on the dev console and trying to figure out if I can write to the session props from there.
edit: seems like something like __client.page.sessionCustom.root.value.value.get('public').value and __client.page.sessionCustom.root.value.value.set('public', 'newValue')
After spending some time working in this and testing I'm trying to understand why Ignition by default sets properties to public.
My biggest concern is a bad actor being able to change a property value on a View in the UI (like a view parameter for a specific location or piece of data) and viewing data they shouldn't.
I think its probably just a shift from Vision where everything seemed pretty sandboxed off to a more traditional Web Dev security mindset of starting with the assumption of never trusting something from the UI.
Can anyone from IA chime in here to alleviate my concerns or provide any more resources on Perspective security best practices?
Your concerns are only due to using a non-documented "feature" of Perspective. Don't make custom page props and you have no problem. All other properties can be configured in the designer to the desired level of privacy.
You need to convince IA to get these upgraded to an actual supported feature before anything else.
If you can't (or won't) use my toolkit's pageVarMap(), you should be using custom session properties with per-pageId mappings to track page-specific values. That is the supported path.
(FWIW, view parameters have always been required to be public, because view parameter passing is done in the browser, not the gateway.)
Thanks for the suggestion phil. We aren't using custom page props anymore, we've moved everything into the session, segregated by page id where needed which has been working great.
My concern is for example a param going into a View for a specific ID for data that just loads based on the ID passed in. If someone were to figure out how to change that ID in the browser the View might load data the user is not allowed. Seems like the best practice is any property like this or maybe even all of our custom props and view parameters we should set to protected at a minimum.
Mostly wondering
Why are these defaulted to public? My guess is backwards compat
Is there any downside to setting all of our view params and custom props to be protected or private? This would be pretty easy for us to do with some scripting on all the JSON files on the gateway
I know my opinion is just one, and isn't worth much. I just wish all the props were private/protected by default and the public exposure to the browser console was an opt in. We can work around it, but feels like something we will need to audit regularly to make sure someone doesn't miss one. Not a bad thing per se just more work.
Of course, we should also configure the security on event scripts or do our own checks when loading data (not trust the UI) but I'm more thinking along the lines of bidirectional bindings as well as browser console/xss issues.
I'm not sure the access controls on view parameters are effective. I'll have to explore some more, but my prior explorations indicated they have to be in the browser.
I agree that all custom properties everywhere in Perspective should default to private. (But what you are calling page custom properties are not, they are dynamically created properties under {page.props}, not {page.custom}. That latter doesn't exist.
Yes, you're right. I meant page.props.custom we we have totally abandoned
I did figure out how to read/write View custom properties in the console and tested that with the access levels. It worked as expected. I think going forward we will have a policy to make any property we use (binding, scripting, etc.) have access of private. Since there doesn't appear to be a way to default all props to private we'll probably have to make some tooling to crawl the views on disk and set the access level of these. What would be nice would be a gateway setting for default property access.
I was able to set a view parameter to "Private" and stopped seeing it in the browser console, and could not write to it from there. All the rest of the functionality of the View kept working.