Symfony3: Adding extra security before loading login form - javascript

I have been creating web application using symfony 3, and I've been requested to add an extra layer of security. I need to check for a key (or token) before loading the login page.
I've been reading the docs, but majority apply only for the login page. The key (or token) is provided by a custom backgroun app and when the user tries to load the login page, the app passes the key via javascript.
So, I'm looking for a way to first look for the key, compare it to a key stored in my database (may be security.yml). If the key matches, then load the login page (key is no longer needed after this).
Is there a way to do this?
Edit:
Optionally, may be is there was a way to grab the key (that is being passed via javascript) and then instead of connecting to the database, compare the key in Twig. So, using Twig to get the key?

Think about security layer like this , user have hardware tokens like yubikey.
https://www.yubico.com/start/
then you install bundle like this
https://github.com/pmdevelopment/yubikey-otp-bundle
and with that you can create 2FA hardware based security layer (you have service for youbikay auth - you can authenticate user with this at any time - depend on your need .

If I understood correctly your specs, you could:
Load the page without the login form
Do an AJAX request that sends the token/key to your server
If the key is valid return HTML for the login form with a hidden input field that holds the value of the token
Validate the token when processing the submitted form
Since 4 is usually done automatically you will have to hook in via a listener, or just submit the login form to a controller and log in the user "manually".

Related

Prevent a user to complete two times a form in javascript

I created a form with Html, CSS and JavaScript and an API with ASP.NET for the HTTP request. Users will have a link to fill in the form. Is there any browser id or IP which I can get so prevent the user to submit multiple times the form?
Disable the submit button is not an option
The form has to be anonymous so a unique id for the users is also not an option
you could make like a cookie in java script that doesn't expire. after that you could make a if else state and check for the cookie if it exists in the browser
value_or_null = (document.cookie.match(/^(?:.*;)?\s*MyCookie\s*=\s*([^;]+)(?:.*)?$/)||[,null])[1]
// Put your cookie name in in place of MyCookie.
if (value_or_null = 1)
{
//redirect to other page
}
else
{
// let him do the form
}
There is no 100% safe way, as returning users could have cleared they cache or something. Also, tracking the IP could potentially work, but you ask for full anonymity...
If you want your server to have authority on this decision, the only information you will have or can use is the IP address. Even that would not be accurate if your users hop on different VPNs and stuff.
What I think could work is if the link for the users to access the form is unique for each user. You'd generate a UUID, that way it cannot be guessed if users want to answer more than one. That UUID would have no link to any user, it would just be stored in a list of VALID UUID and get removed when the user uses it to answer.
The link would provide the UUID through query param, the javascript would then add its value to the form when being sent.
If you do not link that UUID to a userId or if the email sent (or its content) is not stored, this would provide anonymity.

Securing PHP scripts - Shopify

Basically my question is similar to this one:
How to secure php scripts?
with one slight difference, the other side is Shopify.
Background info:
Shopify user bought some credits (Audible style), and wants to know how many he has available. He logs in into his account, and it says there that he has X credits.
That number comes from AJAX call to my server (I have full control), where there is a simple php script which checks the value in db (which is updated using webhooks from Shopify, each of which needs to be verified so they are secure, I think).
The script uses customers ID for a look up, and that value needs to be passed to the script somehow, and that allows someone external to just keep running it until he has all IDs and corresponding credits values.
So, my questions is, how do I stop that? How do I ensure that only authenticated users can check it, and only for their IDs.
There is plenty of info on Shopify docs about securing the connections the other way, i.e. to make sure only correct scripts have access to the Shopify db, but nothing about my problem.
As far as I know I only I only have access to JS on Shopify, which creates the problem, because everything I send to my server is visible to all.
Thanks
EDIT: I just read up on CSRF. I can easily implement checks for origin and headers, but these can be faked, right?
EDIT 2: I got around this problem by using metafields. So, instead of storing all that info on my server's db, I just use Customer Metafields to store the available credits. Webhooks are secure so that's brilliant. It still doesn't solve a problem with the next stage though. Customers will still need to be able to use their credits and get digital products, which are generated by my server. So I still need to verify the requests.
EDIT 3: Comment by #deceze and answer by #Jilu got me thinking. Yes, you are correct, I need to do that, but I don't have access to back-end on Shopify, so I cannot create session. However, what I could do (if I figure out how in js) is hash it. PHP login scripts operate on password_hash. That way you do not store a password in the db. Password get's verified again hash (or whatever you call) in the db, and it's either true or false. If true, you are logged in. So I could try to generate a token using a specific string (make it very long) and user id. Send it with the request, and using password_verify or what not, check it against the users. The one that pops positive is logged in user who requested the information. That is assuming I can hide the string in the Shopify...
Step1: Do a session login system.
Step2: Before the Ajax, generate a random token in your form or request page, put it into a input display none, send it with POST.
Verify each time if the token is set and is the same that you got.
You have now verified if the user is really logged in with session.
And you checked that he is from the right page.
You create a token out of shared secret (both Shopify and server have it), and client ID.
On Shopify:
{% assign my_secret_string = "ShopifyIsAwesome!" | hmac_sha256: "secret_key" %}
My encoded string is: {{ my_secret_string }}
On server:
We gonna be checking received hash value against values in our db, so we need to hash local client IDs using the same algo and key (that probably should be done on receiving the Customer Creation webhook).
Hash IDs using: http://php.net/manual/en/function.hash-hmac.php
$hashed_id = hash_hmac('sha256', '$client_id', 'secret_key');
Compare hash using: http://php.net/manual/en/function.hash-equals.php
$check = hash_equals($hashed_id, $received_id);
Then all that's requires is to loop through the db until you find a match. There may be quicker ways of doing it.

Is it possible to prevent that a popup be opened directly as opposed to being opened by Javascript?

The application I'm working on relies on many popups. Those popups rely themselves on query strings. If someone can just type the url in the browser address bar, the page will throw an error as the query strings values are dynamically constructed.
function myFunction(id)
{
window.open("mypopup.aspx?id=" + id);
}
Is there a why to prevent the page from displaying if the requester of the page is not a Javascript? If someone type something like:
https://mycompanyname.com/path/mypopup.aspx
It shouldn't let the user do so. Or, at least check whether the requester is not javascript so I can display a message or redirect the user to a different page? Otherwise, without all those pieces of data needed to construct a request, the page will throw an exception.
Thanks for helping.
Validate the query string directly in myPopup.aspx, if something is missing just redirect or display a message.
Use the Request.QueryString collection to validate in myPopup.aspx.
There is no easy way to validate if the request came from javascript as far as I know. You could try creating a token to validate that the sender is the one you expect, but if you only need to validate the parameters, no need to worry about who is sending the request.
The page cannot differentiate how it was requested, if both requests come from a same browser.
However, you can include in query string to differentiate them.
For example,
window.open("mypopup.aspx?request=javascript&id=" + id);
If a user intentionally type in https://mycompanyname.com/path/mypopup.aspx?request=javascript, so be it. I won't worry about it.
Popups are browser windows too. So it will be tricky to check if the window requesting the page is normal window or popup.
You should restrict the users to see on what url the popup is being opened you can hide the address bar. So user can not copy or know the what's in the url.
window.open('/pageaddress.html','winname','directories=no,titlebar=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=no,width=400,height=350');
Setup a token based validation. Make request to server(Ajax request) to get a random token(with one time validation mechanism and expire it), You can send the token in the query string and validate it on server if it's same issued token. Identify if the requested page have valid token(popup) otherwise deny the request or show error message. Think of how captcha works, you just need to do it programmatically.
Though it's also not the best solution as token information can be sniffed through network traffic tracker tools like fiddler but it's will work to prevent manual requests.

Get or Pass Sensitive Data via AJAX in PHP

I want to update a row of data in a database using Ajax and PHP; however, I'm struggling with the following issue: the field in the database to update (henceforth the id) is dependent on the page the ajax request is sent from.
I need to get this id to my PHP script that Ajax calls, however:
I don't want to set the id in a data attribute or hidden input on the page because these can both be manipulated by a malicious user.
Similarly, identifying the id using the referring URL is also prone to spoofing as $_SERVER isn't secure.
I can't set the id in a SESSION variable (or COOKIES) because the user could have multiple pages open and the SESSION would only hold the last page id that was opened.
The only solution I can think is to create a map of random tokens to id's in a table in the db and pass that in a SESSION variable (as per #3 above), then check the table for the token and grab the respective id that way. Seems somewhat convoluted though.
Are there any other options or thoughts? Thanks.
This is a problem related to OWASP Top10 A7 (Missing Function Level Access Control).
There might be no issue with putting your ID on the page so the page can send it back - you just need to validate that the actual save request is permitted for the user.
Just think, regardless of whether you put the ID on the page or not, the page does know the base url for performing the action, so they could go ahead and guess IDs anyway.
Simplify your logic. Pass some sort of indicator of what type of id is in use from the client to the server.
If you create overly complex application logic to address a security concern you will probably have more problems with your code than improvements in security.
Use SSL/HTTPS and a WAF (web application firewall - like mod_security).

Capture details of Facebook message in application database

In my Facebook application I am displaying a message window using FB.ui { method: 'send' ...}. I would like to capture the list of recipients (stored in the 'recipitents []' hidden form field) as well as the message text in my application database.
Is there a way to do that?
Here's what I have come up with so far:
Dynamically set the onclick attribute in the DOM element (which corresponds to the Send button. So far I have been able to do that using the browser development tools (e.g. F12 in IE9) but not in code; it could be tricky since the dialog doesn't exist at load time). Unfortunately I haven't been able to define a Javascript function that was in the right scope (I thought there was only a global scope) for the onclick callback to find it.
Construct the Facebook Send dialog from more elementary building block (e.g., friend picker, send method invocation) so I 'own' the click event.
Clone the FB.ui() code and modify it to include additional parameters when calling the redirect url.
Require the user to include me in the To list (really only last resort), or default the 'to' field to the application's user id.
Finally, I expect to be able to call my web service from Javascript to record the message details in my application database.
I'm pretty sure this is not available via the API by design. The Send button operates in an iframe so browser security will prevent you from accessing its internal state via Javascript.
Some other methods (such as using FB.ui dialogs to post to the user's wall) provide a post ID in the callback and you can check this in the Graph API, but the Send button doesn't return anything like this.
For the Send button you can subscribe to the message.send event in the Javascript SDK and receive a callback with the URL which was sent, but not who it was sent to. ( https://developers.facebook.com/docs/reference/javascript/FB.Event.subscribe/ - the event itself isn't currently listed there, but does exist)
I can't think of why you'd want to do this type of tracking, it seems like a use-case with very few policy compliant applications.

Categories