Updated 2017-05-24
Visualforce respects Field Level Security when using apex:inputText. It will appear editable if the user has Edit permission on the field, Read-Only if the user has Read permission on the field, and will not be rendered at all if no access is granted to the field. When writing Visualforce, it helps to remember that System Administrators have Edit Read-Only Fields, which overrides the Edit permission on a field (but they won't have any access without Read access to the field). Always make sure you're testing with a profile that does not have the Edit Read-Only Fields permission.
Original Answer
apex:inputText
does not honor Field Level Security. Use apex:inputField
instead. See Enforcing CRUD and FLS for more details.
The system context is not just about sharing. From the docs:
In system context, Apex code has access to all objects and fields— object permissions, field-level security, sharing rules aren’t applied for the current user.
setting a class to run "with sharing" tells Apex to apply the current sharing rules for the current user, but field level security, object permissions etc still don't get applied. The class doesn't run in user mode though - only standard controllers or code run via execute anonymous run in user mode.
If you have a controller class without sharing that causes a trigger to be fired, the trigger will still run in the system context (i.e. no sharing, FLS, object security). If you need to respect sharing your trigger will need to delegate to a class declared as 'with sharing'.
There's a blog post from Abhinav Gupta that covers some of this, although its coming from the other side and explaining how delegating to a 'with sharing' class takes a trigger out of full system context:
http://www.tgerm.com/2011/03/trigger-insufficient-access-cross.html
Guest site user is a slightly different situation, in that some of its ability to access objects is constrained by the user license. I've hit the issue where I was trying to update something that the guest user profile should only have read/create permission on, so I thought I'd get around it using a custom controller (running in the system context). This had worked for me for contacts, but for another standard object I received an error that the license didn't support the operation. The license issue persisted even if I executed the update from an @future method. So no, I wouldn't expect it to have as much clout as the system administrator, although actions that should be prohibited by the license may sometimes work.
Best Answer
APEX and API are two different things. Data Loader uses the API. APEX is executed on the Salesforce server in system mode.