When you return to certain websites, sometimes they have popups or messages which show to inform users of new updates to the site or important changes.
I'm having issues understanding how these are implemented because these messages only show up once. How would a backend know that a user has already seen a backup and would it not be strenuous checking every time a page is returned to if a user has seen a certain message?
There are multiple methods which I have thought of to implement this functionality:
Storing a cookie which is checked by the backend to see if the user has seen a recent message or popup.
Have a table in a database named 'viewed_message' or something that states all the users that have seen a certain message or not.
How would a website go about creating one-time only popup/messages? Thanks.
Typically cookies are used for that sort of thing. Just check the existence of some firstVisit cookie and pop up the message if it's not there. Keep in mind this means if you clear your cookies you'll see the popup again.
edit:
This is an example from the Document.cookie docs on Mozilla:
function doOnce() {
if (document.cookie.replace(/(?:(?:^|.*;\s*)doSomethingOnlyOnce\s*\=\s*([^;]*).*$)|^.*$/, "$1") !== "true") {
alert("Do something here!");
document.cookie = "doSomethingOnlyOnce=true; expires=Fri, 31 Dec 9999 23:59:59 GMT";
}
}
I think you are on the way.
Cookies are there for that, create a cookie wich never expires and be happy.
If you want to use in wich others browsers, check if the cookies exists if dont look in table and store a cookie.
Related
I have an Html page with a load of javascript that changes between views.
Some views require the person to be logged in, and consequently prompt for it.
How can I note the person has successfully logged in, using the javascript, that will not be a security issue, but will mean the person does not have to repeatedly log in for each view. I do not want to keep on going back to the server each time.
Edit:::
To explain more. Here are the problems I see.
Lets say I have the following in my javascript:
var isLoggedIn = true;
var userEmail = "myemail#mysite.com";
Anyone can hack my code to change these values and then get another person's info. That is not good. So instead of isLoggedIn do I need something like a hashed password stored in the javascript:
var userHashedPassword = "shfasjfhajshfalshfla";
But every where I read, they say you should not keep any password stuff in memory for any length of time.
So what variables do I keep and where? The user will be constantly flicking between non-user specific divs and user-based divs, and I do not want them to have to constantly log in each time.
****Edit 2:*****
This is what I am presently doing, but am not happy with.
There is a page/div with 3 radio buttons. Vacant games (does not require user information), My Game (requires knowledge of user and must be signed in), My Old Games (also requires logged in status).
When first going on the page it defaults on vacant games, and gets the info from the server, which does not require login.
In two variables in the javascript I have
var g_Email = "";
var g_PasswordEncrypted = "";
Note these are both 0 length strings.
If the user wants to view their games, they click the My Games radio button. The code checks to see if the g_Email and PasswordEncrypted are 0 length strings, if they are it goes to a div where they need to login.
When the user submits their loging info, it goes to the server, checks their details, and sends back an ok message, and all the info (My Games) that the user was requesting.
So if the login was a success, then
g_Email = "myemail#mysite.com";
g_PasswordEncrypted = "this is and encrypted version of the password";
If there is any failure in login, these two are instead set to "".
Then when the user navigates to any page that requires login, it checks to see if these two strings are filled. If they are, it will not go to a login page when you request information like My Games.
Instead it just sends the info in these strings to the server, along with the My Games request. The server still checks these Email and encrypted password are valid before sending back the info, but at the client side, the user has not had to repeatedly input this info each time.
If there is any failure in the server request, it just sends back an error message (I am using ajax) in the callback function, which knows to set the g_Email and g_PasswordEncrypted to "" if there is anything wrong. (In the latter case, the client side knows it has to re-request the login details because these two strings are "").
The thing I do not like is I am keeping the Encryted password on the person's client machine. If they walk away from their machine, someone can open up the debugger in something like chrome and extract these details, and then hack it into their machine some time later.
If javascript loads content for each view from the server then it is for server to know if a current session belongs to logged user or not. In case the user is not logged, the server responses with prompt to login, otherwise it sends content of the view.
If javascript bulds content for the views deriving it from the data that was already received from the server then it should use some variable keeping state of the user (logged/not_logged). And depending on that value javascript will either show a prompt to login or display required content of the view.
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;
}
I wonder what are the techniques i can use to avoid users to post form twice when they refresh page and chose submit again?
e.g. i have form inside regiter.php and process it as well inside register.php.
1st i could process in another file e.g. register_process.php and redirect to register.php, but then i have to create about 20 new pages and relocate a lot of code, i dont want that option.
2nd i could play with headers i dont remember exact trick but had some bad experience with that - users seen old data on page after refreshing it...
3rd i could just redirect upon success to some dummy.php and from dummy.php jump back to register.php then even if they refresh page browser would not re-post, however it does not protect against them using back button and choosing re-post, i know i could expire page, but i find that annoying experience for me and probably other users to see page expired error.
4th use some unique "access key" for each form once page loaded that will post with form and once used cannot be reused, however i kind of struggle with logics of that feature. how do know key was used without storing it in MySQL DB, i think time based accesis not great either because some users can take long between page open and form submit.
I need more suggestions how to avoid users reposing form again.
Try this:
<?php
session_start();
if( strcasecmp($_SERVER['REQUEST_METHOD'],"POST") === 0) {
$_SESSION['postdata'] = $_POST;
header("Location: ".$_SERVER['PHP_SELF']."?".$_SERVER['QUERY_STRING']);
exit;
}
if( isset($_SESSION['postdata'])) {
$_POST = $_SESSION['postdata'];
unset($_SESSION['postdata']);
}
This will basically save the POST data and cause the browser to re-request as a GET request.
5th. Use AJAX or jQuery and when the form is clicked on the page submit that data in the background. Output a response to the screen. Mark that form as submitted, or save to a session, and when they refresh they will not be able to submit the form again.
In my opinion it is the best way to do it anyway. I had a scoreboard with 20 or more forms it is worked really well to send the data without refreshing. You can return a response and make the page look very professional. Using jQuery you can also use some great form validation to make sure that they are submitting the fields that are required.
I think that the best solution would be something like this:
* create a md5 or base64 of posted data
* compare this hash with a session variable (let's call it $_SESSION['repost'])
* if hashes match, skip whatever this save should do and output a warning
* if hashes do not match, or hash is not present
* assign session variable with current hash
* do whatever save should do
When you consider the first option, I don't know about the design (programming design ^^) of your website, but you should only need 1 page. Let's says you call redirect.php with all the parameters, you should call your controller and your controller should know regardless of the parameters what to do with them.
It is a good habit to be able to do some abstraction and good design when programming, it help alot in those situation.
Other way is store the last post in the session variable, and check if is equal, like this:
<?php
... program ...
if ($_SESSION['PREPOST'] == $_POST) {
// DO SOMETHING
}
... program ...
$_SESSION['PREPOST'] = $_POST;
?>
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.