I am trying to dynamically retrieve images from Sugar CRM to display on a website. When I am logged in, the images display alright. When I am logged out, I am also denied access to the images hence the wider public will not see the images.
How can I ensure that a logged in header is sent on the webpage without exposing my username and password? Or how can I display the image on the webpage?
I had to do something like this earlier in the year. I can't provide all of the code, but my idea was to create a separate Entry Point that did not require authorization. From that Entry Point file I essentially spoofed authentication and called the normal download.php Entry Point. It went something like this (keep in mind this code was invoked by hitting index.php?module=MyModule&entryPoint=MyEntryPoint)
unset($_REQUEST);
$_REQUEST['entryPoint'] = 'download';
$_REQUEST['id'] = $focus->$field;
$_REQUEST['type'] = 'SugarFieldImage';
$_REQUEST['isTempFile'] = '1';
$_SESSION['authenticated_user_id'] = '1';
require_once('download.php');
One caveat I found there was that I needed to check first for an existing session before setting $_SESSION['authenticated_user_id'], otherwise an actual Sugar user who used the website would go back to Sugar and find that his/her session had been escalated to an Admin account(!). So, I added a check before setting it that way, and code to re-set it back to the original value. Something like this:
if(!empty($_SESSION['authenticated_user_id'])){
$old_session_id = $_SESSION['authenticated_user_id'];
}
$_SESSION['authenticated_user_id'] = '1';
require_once('download.php');
if(isset($old_session_id)){
$_SESSION['authenticated_user_id'] = $old_session_id;
}
Issue:
An authentication server (not under my control) is stripping get values after the first from the returnUrl. Is there any way to work around this? (Or around the larger problem as a whole?)
e.g. http://authentication.corporate.com?returnUrl=http://localserver/addcomment.php?FirstName=Sally&SecondName=Sparrow redirects as http://authentication.corporate.com?returnUrl=http://localserver/addcomment.php?FirstName=Sally, stripping any subsequent $_GET values.
(I am led to believe through my research that the stripping of the $_GET values may be an issue with what the authentication server is doing, but I have no way of getting access to it. If this is the case, is there a workaround? If this is not the case, what am I doing wrong?)
Context:
I am writing part of a web application which is to allow users to add comments to documents. The web application must retrieve the user's (correct) corporate username, first name and last name.
I am updating a previous version of this web application which allowed users to add comments in a two-step process.
Step 1 After clicking an 'Add Comment' hyperlink, the user is authenticated and a returnUrl value directs them to a page where they may add their comment. http://authentication.corporate.com?returnUrl=http://localserver/addcomment.php
Step 2 In addcomment.php $_POST values have been retrieved (and confirmed as correct) from the authentication server. The user may then enter their comments in a textarea and submit them via action=post to a final page which inserts the comment and user information into a database.
I would like to reduce this to a one-step process where the user may type in a comment on the main page. The way I am attempting to do this is by passing the comment as a $_GET value to be returned via the authentication server. e.g. http://authentication.corporate.com?returnUrl=http://localserver/addcomment.php?FirstName=Sally&SecondName=Sparrow along with the $_POST values.
I have a service in AngularJS that generates all the steps needed, the current state of each step (done, current, show, etc) and an associated directive that actually implements the service and displays the data of the service. But, there are 2 steps that are divided in 4 and 3 steps each:
Step one
Discounts
Activities
Duration
Payment Length
Step two
Identification
Personal data
Payment
How can I "save" the state of my form in case the person leaves the site and comes back later? Is it safe to use localStorage? I'm no providing support for IE6 or 7. I thought of using cookies, but that can end up being weak (or not)
Either local storage or cookies should be fine. I doubt this will be an issue, but keep in mind that both have a size limit. Also, it goes without saying that the form state will only be restored if the user returns on the same browser, and without having deleted cookies / local storage.
Another option could be to save the information server side. If the user is signed in, you can make periodic AJAX calls with the data and store the state on the server. When the user finishes all steps, you can make an AJAX call telling the server to delete any saved data it might have. This allows you to restore state even if the user returns on a different browser, as long as he is signed in.
Regardless of what direction you go with this, you can use jQuery's serialize method to serialize the form into a string and save it using your choice of storage.
I was thinking about this and it appears POST only a little less vulnerable and somewhat harder (do to requiring the user to click something).
I read about token ids and double submitted cookies and i am not sure what the difference is
http://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29_Prevention_Cheat_Sheet#Disclosure_of_Token_in_URL
http://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29_Prevention_Cheat_Sheet#Double_Submit_Cookies
Right now i have the user id (PK in my table) and a session id so you cant simply change your cookie ID and act like someone else. Now it seems like i put the session id as a token in each of my forms and check them bc attackers cant guess these tokens. However i dislike the idea of putting the session id into the page for ppl to see. But really, is there a problem with that? short of having the user copy/pasting the html is there any attacks that can happen due to the session id being in plain view in html?
If the user can copy a link with a token in it, this is very insecure. Likewise for the current address: if you use a static session ID, a referral to an outside site or a screenshot will render the session compromised. Even if you don't have a static session ID, the user can put his mouse over a link and it will show in the bottom of his browser, and then take a screenshot, once again rendering his session compromised.
The session-ID is known on client side anyway. How else would they send it with the requests?
Say a user is browsing a website, and then performs some action which changes the database (let's say they add a comment). When the request to actually add the comment comes in, however, we find we need to force them to login before they can continue.
Assume the login page asks for a username and password, and redirects the user back to the URL they were going to when the login was required. That redirect works find for a URL with only GET parameters, but if the request originally contained some HTTP POST data, that is now lost.
Can anyone recommend a way to handle this scenario when HTTP POST data is involved?
Obviously, if necessary, the login page could dynamically generate a form with all the POST parameters to pass them along (though that seems messy), but even then, I don't know of any way for the login page to redirect the user on to their intended page while keeping the POST data in the request.
Edit : One extra constraint I should have made clear - Imagine we don't know if a login will be required until the user submits their comment. For example, their cookie might have expired between when they loaded the form and actually submitted the comment.
This is one good place where Ajax techniques might be helpful. When the user clicks the submit button, show the login dialog on client side and validate with the server before you actually submit the page.
Another way I can think of is showing or hiding the login controls in a DIV tag dynamically in the main page itself.
You might want to investigate why Django removed this feature before implementing it yourself. It doesn't seem like a Django specific problem, but rather yet another cross site forgery attack.
2 choices:
Write out the messy form from the login page, and JavaScript form.submit() it to the page.
Have the login page itself POST to the requesting page (with the previous values), and have that page's controller perform the login verification. Roll this into whatever logic you already have for detecting the not logged in user (frameworks vary on how they do this). In pseudo-MVC:
CommentController {
void AddComment() {
if (!Request.User.IsAuthenticated && !AuthenticateUser()) {
return;
}
// add comment to database
}
bool AuthenticateUser() {
if (Request.Form["username"] == "") {
// show login page
foreach (Key key in Request.Form) {
// copy form values
ViewData.Form.Add("hidden", key, Request.Form[key]);
}
ViewData.Form.Action = Request.Url;
ShowLoginView();
return false;
} else {
// validate login
return TryLogin(Request.Form["username"], Request.Form["password"]);
}
}
}
Just store all the necessary data from the POST in the session until after the login process is completed. Or have some sort of temp table in the db to store in and then retrieve it. Obviously this is pseudo-code but:
if ( !loggedIn ) {
StorePostInSession();
ShowLoginForm();
}
if ( postIsStored ) {
RetrievePostFromSession();
}
Or something along those lines.
Collect the data on the page they submitted it, and store it in your backend (database?) while they go off through the login sequence, hide a transaction id or similar on the page with the login form. When they're done, return them to the page they asked for by looking it up using the transaction id on the backend, and dump all the data they posted into the form for previewing again, or just run whatever code that page would run.
Note that many systems, eg blogs, get around this by having login fields in the same form as the one for posting comments, if the user needs to be logged in to comment and isn't yet.
I know it says language-agnostic, but why not take advantage of the conventions provided by the server-side language you are using? If it were Java, the data could persist by setting a Request attribute. You would use a controller to process the form, detect the login, and then forward through. If the attributes are set, then just prepopulate the form with that data?
Edit: You could also use a Session as pointed out, but I'm pretty sure if you use a forward in Java back to the login page, that the Request attribute will persist.