I have a controller like the image below. This controller hides the relevant record in the database when the fetch request is sent. Do I need to use http post for such operations in this project that I wrote with Entity framework core? The problem with this controller is that the admin executes the javascript code fetch(https://localhost:5001/admin/deletepost?delete=url) on any page. As soon as this get query runs, the relevant record is hidden or deleted from the database. Is it safe as it is? How can I make it more secure? Thank you very much to everyone who replied.
Although this method is only accessible to the admin, will the deletion of the record as a result of the admin sending this request cause a deficit?
For several reasons, POST is more secure than GET.
GET parameters are passed through the URL. This means that the parameters are stored in the server log and browser history. When using GET, you can also easily change the data submitted to the server because it is in the address bar.
The problem when comparing the security between the two is that POST may block temporary users, but it cannot block malicious users. It is very easy to forge a POST request and should not be fully trusted.
The biggest security problem of GET is not the end user's maliciousness, but the third party sending a link to the end user.
Another point is that you must consider where to use GET and POST, because GET should only be used for operations that do not change database information, and only request or read information and POST data should be used when the data will be changed.
Some web scanners will automatically click on each link (usually a GET request) instead of in a button or form (usually a POSTS request) to avoid changing the database, but for example, if you perform a delete operation after the link, you The risk of clicking on the link may be easier with more automated tools.
Related
I've made a simple webapp that is going to show some data in a table, which will be updated weekly.
This update it done in the backend with some python code, that scrapes and alters some data, before putting it in a SQLite database.
After doing some reading I learned that to deliver that data to my webapp I should make a API with Flask, that can take that data and deliver it to the JS in my webapp in form of JSON, which then can use the data to populate the table. However, I should secure my API with username and pw. But as its a JS frontend that will retrieve data from the API, there is really no point, as the username and pw will have to be hardcoded into JS, which then can be read by the users. (I think)
Should I expose my API to everyone, or is this not the way to go to be able to use SQLite data as a backend for my webapp? I am fine keeping the API to a GET only.
You are correct, it is pointless for you to secure your API. Securing an API is only needed in certain circumstances.
If you are accessing data that you don't want anybody to see, perhaps through a backend call, then it would make sense to add in some form of security (normally an API key or Authorisation tokens in your request headers).
However, if you are making calls from your front-end (i.e. client side) to a backend API, then there is no point putting additional security there as the user can already see the request and already has access to the data the API is returning - so by securing it you are achieving nothing.
Normally, if the page the user is visiting contains sensitive data that you don't want everyone to see, you would take steps to secure your website instead (for example protecting it with a login for username and password before you can access that page). If you were to take this approach, where the website is protected by username and password, then you can update the API to make sure it does not respond to requests where the user is not authenticated (e.g. by generating a session token or something unique for each logged in user).
If you have a look around on websites that have lots of free data available, you will find they all have front end API calls that are completely unsecured (because it is pointless if the data is already free to access). Some websites do take steps to try to make sure it is their own website that is calling the API, but even then it is a bit pointless as web scrapers can always extract the data from the HTML.
Take a look at this page which outlines authentication headers. This simpler route is to hard code the header info in Flask to make it a little more secure. You could also try the more involved route of reading header info from your db. What's currently working for me to read from postgres db is below so you may modify it slightly for sqlite.
def valid():
headers = request.headers
auth = headers.get("X-Api-Key")
user = User.query.filter_by(apikey=auth).first_or_404()
print('from search of db ',user,'',auth)
return str(user)
As you mentioned, you plan to show a public data - then it can be used even
without authentication. Otherwise I think it can take too much unnecessary time spent on that.
As you have just a simple and single table from database, I believe that you don't need an API. You can just create HTML template and render it with data. Some examples can be found here and few more here.
I got questions about security. lets say I have data in a div like so
<div id="Q9vX" class="mainContent" data-compname="comp1" data-user="57f70c8e78ae49d41c78876a" data-shortid="Hy85nKVR">
and I do a post request that sends the compname and user id .Couldn't someone change the data-user attribute value before it was sent? Since I'm doing DB operations based on the ID in the div can someone change the id and have the operation occur for the id the villain entered and not the one I initially intended. . I use mongodb, heroku, express. I'm afraid of sessions because they expire and I'm not too comfortable with them. What is the standard procedure for something like this?
For example this div is for a review placed by a user that has the id 57f70c8e78ae49d41c78876a. So if everything went normal and the user presses submit the review will be assigned to that users's Id. but lets say someone decides to go into firebug and changes the id would the review be registered to this new ID?
The value could be changed a user through the developer tools or through a cross site scripting attack where malicious code is injected onto the page. This could be done a number of ways such as adding the code to a file on your server, adding the code to your database if it uses a CMS, or through another means such as a browser extension.
If you have no server side access controls, someone could write a script that compromises the availability or integrity of your data. The availability could be compromised through a denial of service attack where thousands of fake requests are sent to the server trying to exceed the number of concurrent database connections preventing a legitimate user from connecting. The data integrity could be compromised by sending lots of fake requests to the database which could be difficult and time consuming to identify and remove. Also if the review is like a comment box where users can enter data that's displayed on the site, it could be used to inject malicious cross site scripting code.
If you are concerned about security I recommend that you implement access control such as sessions, sanitize the data coming in and going out of your database, and use a secure HTTP connection on your web server.
The Express JS website have an article about security best practices.
I have been thinking over this issue from past few months. Recently, I have started with complete JS Built front-end, where the forms are posted using Ajax.
I have a doubt, how to recognize on the server side, from where the data is coming from. Is it coming from actual form event or it is coming from browser console.?
What I have tried:
Creating a two way handshake: Before posting the form, the Application will contact the server, and the server will send a token inside the cookie, which will be sent back with the form post. But, even if we post by browser console, that cookie will go carrying the token. So, Failed.
Binding Hidden Field: But if someone, is posting the data from browser console, he would definitely look for the hidden fields as well. Basically, he'll replicate my AJAX to send the same request, in the same fashion. FAILED!!
I am not able to figure out this part. Can anyone help?
Thanks in advance.
Rule #1 of programming for the Internet: Never trust anything from the client. EVER.
Rule #2 of programming for the Internet: Never trust anything from the client. EVER.
Rule #3 of programming for the Internet: You can not make the client trustworthy.
I know the first rule is duplicated twice, but it is worth it.
There is simply no way to do what you intend to do.
A person who wishes to send data to your server, via an AJAX request or a POST request, can easily do any of the following:
Modify the form using browser tools or a proxy and force-feed in whatever information he wants.
Capture the entire transaction, through a tool like fiddler2, and change the values and re-send them. No browser needed.
Modify the code running from your site to send (or allow) whatever data he wishes to send.
Use a tool like Curl to fake an browser and send whatever information he wishes to.
There is simply no way of knowing, on your server, where that information came from.
From a security point of view, you simply can not trust anything -- ever.
Validate the credentials, give the user a login token (usually a cookie) and then still be suspicious of everything the client sends you. If there is something that shouldn't be changed or updated, make sure your back-end doesn't allow it to be changed or updated.
We have tons of code in our application that looks like this:
if (user.HasPermission("MayUpdateFirstName") {
record.FirstName = FormData.FirstName
}
That way, if FirstName is passed in, and the user can't modify it, then it doesn't get modified.
I am working on two domains sharing the same database table an same users. They are both hosted on the same box, but contain different data and serve two separate but similar purposes.
I have: Login process ** with **JQUERY and AJAX that works fine for both sites.
I want: Once the user is logged in one domain via the PHP function in the AJAX call, to send his information to the other domain, before the full response is sent back to jquery.
In words, set up some kind of listen file in either domain that receives the user's info once they are logged in one of the domains and logs them in the other automatically.
So, jQuery in Site X ==> AJAX / PHP , which checks info, logs the use in site X, sends info to listener.php in site Y,==> back to jQuery in site X
You can pass data fairly easily to another website using a webservice, however you probably want to place security on it to ensure people don't hack your website.
So assume I'm using some external API, where I'm required to send it an ID and passkey such as http://whatever.com/api?id=asdfg&key=_hjkl&request=whatever
I'm going to need to have that ID/key stored somewhere and I could get away with not exposing it to the user by putting it in a database or something, but whenever the request is actually shot off is there no way to hide it?
No, there isn't.
If you want the client to authenticate against a service, then the client has to have the authentication credentials. Anything you give to the client, you also give to the user of the client.
If you want to add some kind of protection, then proxy it though your own server or use a time limited token - but keep in mind that anybody can still hit the appropriate end points to get access.
If you are giving data to the client, then you are running a public API and it is best to think of it in those terms.
If the api provides a POST method, you can use that, without having to show the parameters.
Using POST method to hide URL parameters