Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
For a huge project, we're going to make a "superadmin" login (all other admin work is directly in frontend) for a place where you can alter a lot of things.
As security is really really important, I've been thinking about only allow people with a certain IP to connect. Does anyone knows of websites that do the same, is it overly protective or can you recommend another really secure way of doing admin-work?
We can make it for a specific browser-only if theres some useful possibilities in Chrome or Firefox.
FYI the frontend is javascript, html and css only
It can be good protection, if you can be assured that all "superadmins" will have static IP address, and will not be unable to use application because their IP changed in the middle of the night.
Other method, similar to the one you mentioned, is VPN, where users after connecting to VPN would have an IP address from your private pool, and your application would accept connections only from that pool (even better, you can make apache/nginx vhost for the superadmin application listen only on VPN ip).
Another positive side of the VPN approoach, is that you are securing the traffic too, apart from filtering access.
It won't make sense to do it client-side, since there isn't really anything stopping an attacker from modifying/disabling your JS.
So only secure option is server-side. I've done so myself with a CMS system in PHP.
UPDATE: Sample Implementation
In that project, I used a GeoIP-service (like this one from MaxMind)
function geoIPRequest($ip){
$params = getopt('l:i:');
if (!isset($params['l'])) $params['l'] = '<userIDtoMaxMind>';
if (!isset($params['i'])) $params['i'] = $ip;
$query = 'https://geoip.maxmind.com/a?' . http_build_query($params);
$curl = curl_init();
curl_setopt_array(
$curl,
array(
CURLOPT_URL => $query,
CURLOPT_USERAGENT => 'MaxMind PHP',
CURLOPT_RETURNTRANSFER => true
)
);
$countryCode = curl_exec($curl);
if (curl_errno($curl)) {
throw new Exception(
'GeoIP request failed with a curl_errno of '
. curl_errno($curl)
);
}
return $countryCode;
}
$countryCode = geoIPRequest($_SERVER['REMOTE_ADDR']);
if(!in_array($countryCode, array('DE', 'DK', 'EU', 'GB', 'SE'))){
header('HTTP/1.0 403 Forbidden');
echo "You don't have access";
exit();
}
The code above is adapted from the sample code on MaxMind's website
You'd of course need to adapt it to your use-case. For me specific countries were good enough. If you need to whitelist specific IPs, I'd advised you to create a database table with whitelisted IPs that you then query when someone requests your admin-page.
i have to say, this doesn't sound like a awesome idea
any real security traditionally requires a server component, would recommend the following :
a) make all login pages served over https
b) include a server tech such as ruby/php to do the following:
digest authentication ->
http://en.wikipedia.org/wiki/Digest_access_authentication
which is basically
login details stored in a db (make sure you only store password hashes + salt in db!!!)
php/ruby compared login details to db log in details
once authenticated store this authenticate state as a digest cookie
see here for php implementation : http://www.php.net/manual/en/features.http-auth.php
but seriously please please don't use client implemented security, it's a bad bad idea
for more security concerns and ideas to watch out for see here ->
http://w3af.org/
http://w3af.org/understanding-html5-security
also very good resource for learning about how amazingly evil and good hackers are, and how to thwart their plans
http://www.lulu.com/spotlight/owasp good books on common security flaws (may be free pdfs online)
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I'm making a website and there is a page on said website which I would like only certain people to access, with a password. I was wondering the best way to go about it simply and securely, and would love some example code if any exists.
To clarify, I would like to add a feature to a page on my website which prevents anyone visiting the site from going to that page unless they enter a password. I'm mostly looking for HTML, JS, or JQuery solutions, as this is only going to be for the users of the website.
The simplest way that I've come across is using an htpasswd file (which looks very similar to /etc/passwd if you are familiar with that), then setting up your webserver to point at it.
# create htpasswd file
htpasswd -c /path/htpasswd
# add user to htpasswd file (you'll be prompted for password)
htpasswd /path/htpasswd loginuser
Within your nginx.conf , set it up like this
server {
listen 80 yourserver;
listen [::]80 yourserver ipv6only=on;
root /var/www/yourserver;
index index.html;
location /public {
# ...
}
# everything under /private requires a login
location /private {
auth_basic "Restricted Content";
auth_basic_user_file /path/htpasswd;
}
}
There's a really good tutorial on this setup, that I shamelessly robbed for this answer here:
https://www.digitalocean.com/community/tutorials/how-to-set-up-password-authentication-with-nginx-on-ubuntu-14-04
Then for anything over/above that, nginx's documentation is excellent as well (if that is the webserver you are using).
https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html
One trap with this setup is that nginx only allows password hashes that are supported by your operating system's crypt module. So linux for example wouldn't necessarily have bcrypt, but most of the BSDs would. You can find what your OS's crypt module supports using man crypt .
|
If you're looking for something where you have a little more control, you can have a URL that you GET a website with form data, which POSTs the login information to a URL you can handle the login details yourself. This is python/flask - I'm not sure it is what you are looking for bsaed on your tags but it may still be helpful.
https://pythonspot.com/login-authentication-with-flask/
I hope this was helpful :) good luck!
Depending on what frameworks, applications etc. you are using to create your website, and If you want create an account system or just a protected area, there are many different ways.
1. .htaccess:
Assuming you are using a NCSA-compatible webserver such as apache and want to restrict access to a certain path, the simplest (yet by far not safest) way to do that would be to use a simple .htaccess-file.
simply put a file with that exact name into the folder you want to protect with following content:
AuthType Basic
AuthName "Enter Credentials Here"
AuthUserFile /full/path/to/.htpasswd
Require valid-user
and create a .htpasswd file in a safe place containing
username:password
or, if you care about people hacking your server getting the password:
username:hash
you can generate hashes using online-.htpasswd-generators.
Make sure to enter the path to your .htpasswd correctly into your .htaccess!
The .htaccess file will make the server ask for basic username/password authentication, show the message "Enter Credentials Here" to the user and require the users browser to send any valid credentials to your server. Valid credentials mean any username/password-pair in your .htpasswd file. Just know that the user's browser will always send the credentials to your server unencrypted, so make sure to enable https, if you care about the password not being stolen from your users. And tell them not to write it down etc. basic password safety.
2. Fancy Account System using SQL
This is more complicated an probably not what you want, so I will just give basic advice: Read about sql injection and make sure you fully understand it and how to avoid it. Read about password hashing and salting. Read about safe passwords (phrases) to advice your users. Read about html forms and how to parse them using your framework. Read about encryption. Then create a concept that fits your needs and implement it.
If you are using PHP then this is simple solution:
<?php
if(!isset($_POST["password"])){
header("location:pwdnotcorrect.php");
return;
}
$pwd=$_POST["password"];
if($pwd!="yourpassword"){
header("location:pwdnotcorrect.php");
return;
}?>
<!--Your HTML Code starts here--->
Send POST request with password to this page using form
If password not correct then this page redirect you to new page.
How can I make an HTML (and CSS/PHP/JavaScript) document which only allows certain IP addresses on a page?
(I am not asking how to find IP address with PHP, but how to allow access to a page based on an IP address.)
put this on the top of your php file and update the allowedIps variable with the IPs that you want to allow.
$allowedIps = ['198.x.x.x', '200.x.x.x'];
$userIp = $_SERVER['REMOTE_ADDR'];
if (!in_array($userIp, $allowedIps)) {
exit('Unauthorized');
}
for non PHP files (eg .html, .css) you will have to update your .htaccess file to add file specific permission. The following SOF thread should help: (assuming you are using apache server)
.htaccess: how to restrict access to a single file by IP?
If you dont want to bother with the code, put your site on Cloudflare and block ips
Try this with PHP :
function CheckIPAccess() {
//allowed IP. Change it to the IP addresses you want to allow to access your webpage
$allowedip = '127.0.0.1';
$ip = $_SERVER['REMOTE_ADDR'];
return ($ip == $allowedip);
}
Usually, IP restrictions are done at the web-server configuration level, so that unauthorized IPs simply can't reach your code at all.
It would actually be quite messy to try to do this kind of check within your application – "you'd undoubtedly miss one" – but the server can easily do it for you.
(I do not recommend attempting to use IPs for privilege checking and so forth ... "IPs change. Frequently. Very messy. Very ...")
Even stronger yet would be firewalls, and maybe VPNs. You really want to keep intruders as far away as possible and to give them as little information as possible. (For instance, why should they even be able to detect that the web-server exists?) Strive to make the entire setup as "hardened" as possible.
I've been working on a social media management tool company for the last eight months. This will be the first major website I release and I have concerns about its security and systems. Obviously security must be a very high priority as my target customers are businesses and individuals who are looking to grow their social followings. If my company's site gets hacked and any of my client's profiles get accessed it would destroy any reputation I had built up and massively slow down progression of the company. So today I'm wanting to share with you all how I wrote the site and see if there are any security flaws I could run into, or if there's a better way to write any of the systems I have in place.
Server systems (Java side of things)
When I first started working on this company I mainly knew Java as I worked with it in a few previous jobs. While other languages may be similar and more powerful, such as C++, I decided to stick to what I knew best. I felt like I still made the correct choice when I was 30,000+ lines in as my servers were running with every little CPU usage and only using 11% - 24% of it's allocated 64MBs of memory. Figured switching at any point to C++ or similar wouldn't be worth the time for such little possible performance improvement.
I have a server running for each social profile. If a client has an account with a Facebook page and two Twitter accounts there will be three servers running for that client. Each one will load specific modules of my software depending on the social platform (Facebook vs Twitter etc). The reason why I wanted one server per social profile is that some payment plans could add more and more social profiles. With more and more social profiles I'd need more and more resources to run that server. I'd rather have the minimum assigned to each social profile server than have to constantly adjust the performance of one large server for a client with 13 social profiles (as an example). Another benefit is to be able to easily remove social profiles, or to "overflow" servers to another box if my current box becomes full and a client request another social profile server. If I would need to expand a large server due to increase request in social profiles on an already full box that may become messy. Is this wrong to do? Is there any flaws in my logic here?
These servers will handle the jobs of post scheduling, listening for "social events" (new followers, direct messages etc) and reacting accordingly to them based on my site's features.
Account registration
I have the typical registration system with an email, a password and a confirm password. I currently don't have a confirm email system but of course that'll be added before launch. Would having a "remember me" option open up any security flaws? If so what ones and what actions could I take to prevent them?
My current system doesn't use MySQL in PHP at all. I use socket communication to send the information to my Java servers to create an account in my MySQL database. There's a Java server used just for "general" communication that isn't meant to be for a specific social profile. The main reason for wanting to create an account on the Java side instead of in PHP is that once I add iOS and Android apps I can easily sent the same sockets to create an account within the app. Would sending sockets to communicate to a Java server to run the MySQL query cause any problems?
What is the absolute most correct and secure way to handle account registration?
Server to browser communication
I am using AJAX to communicate with a PHP script that uses sockets to communicate with my Java servers. Here's a basic example of an AJAX call:
$(document).on("click", ".trash", function() {
//TODO: Add a "are you sure" pop up
var element = $(this).closest(".scheduleddata");
var socialCount = element.attr("socialcount");
var botIndex = element.attr("botid");
element.css("display", "none");
element.html("");
$.ajax({
url: "/client.php",
type: "POST",
dataType: "JSON",
data: {
packet: "62:" + botIndex,
socialCount: socialCount
},
timeout: 15000,
async: true
});
});
Packet ID "62" is meant to delete a scheduled post. Each bot index is a completely unique identifier for each scheduled post. The social count is a counter for each social profile attached to that client's account. For example if I have four social profiles linked to my account I could communicate with a server that has a social count of 1 - 4. If a friend of mine makes an account and links two social profiles to their account, they can communicate with social counts 1 - 2. So the social count is only unique to each client's account. It could be completely possible to make the social counts completely unique. Using the previous example I'd have access to social counts 1 - 4 and my friend would have 5 - 6. Would that be a more ideal system to prevent possible attackers from knowing that social count #1 would always exist?
There is a client/account ID as well, as expected it is the auto incrementing integer in the accounts MySQL table. I used to require the client ID to be sent in the data of the AJAX calls but then I learned that anyone could then communicate with any servers on my service through AJAX and that's obviously not good at all. Currently I have the client ID stored in a PHP session variable when they login. So because I have the first account ever created on the site my client ID is 1, a friend of mine who is helping me test is 2, etc. The client ID is never displayed, loaded, stored, or used anywhere but the session variable. Is there any security flaws to this? If someone could edit that variable and sent the right packets they could communicate with other client's social profiles and that's not good obviously.
For my client.php code I load the address and port of the targeted server:
<?php
if(isset($_POST['packet']) && isset($_POST['socialCount'])) {
$socialCount = $_POST['socialCount'];
if($socialCount > 0) {
echo json_encode(client::send(strip_tags($_POST['packet']), null, -1, $socialCount));
}
}
class client {
public static function send($message, $address, $clientID, $socialCount) {
if(!isset($_SESSION)) {
session_start();
}
$message = strip_tags($message);
if($clientID == -1) {
$clientID = 0;
if(isset($_SESSION['client_id'])) {
$clientID = $_SESSION['client_id'];
} else {
return null;
}
}
$message .= "\n";
$port = 3000;
if(isset($_SESSION["location"][$clientID][$socialCount])) {
$location = explode(":", $_SESSION["location"][$clientID][$socialCount]);
$address = $location[0];
$port = $location[1];
} else {
if($address == null) {
if($clientID == 0 || $socialCount == 0) {
$address = "localhost";
} else {
$reply = client::send("14:" . $clientID . ":" . $socialCount, "localhost", 0, 0);
if(strcmp($reply, "-1") == 0) {
$address = "localhost";
} else {
$result = explode(':', $reply);
$address = $result[0];
$port = $result[1];
}
}
}
$_SESSION["location"][$clientID][$socialCount] = $address . ":" . $port;
}
$socket = socket_create(AF_INET, SOCK_STREAM, getprotobyname('tcp'));
try {
socket_connect($socket, $address, $port);
$message = utf8_encode($message);
$status = socket_sendto($socket, $message, strlen($message), MSG_EOF, $address, $port);
if($status != false && $next = utf8_decode(socket_read($socket, $port))) {
return substr($next, 2);
}
} catch(Exception $e) {
}
return null;
}
}
?>
I feel like most of this code could be improved, I wrote it when I first started learning PHP so please excuse any sloppyness. I am currently storing the returned address:port into a session variable so I only have to load it once. There are some parts of the company that send packets to external servers that my clients set up. So the address/port of their social profile would be public information anyways. I'm blocking incoming communication from IP addresses that are not "whitelisted". These "whitelisted" IPs will be all of my own boxes for now. So I will just be sending packets and not receiving them ideally. Are there any problems with this system?
On a side note, I believe the way Java and PHP encode unicode is different. Whenever I encode unicode and send it from the Java server to the PHP server and I decode it, it doesn't work. How could I fix this problem? I've been having problems figuring this one out for months.
Security measures already in place
As you saw above I'm already using strip_tags and removing all things I can from AJAX calls. I am also buying a standard SSL from GoDaddy, and I'll be upgrading to their most powerful SSL plan once the company starts turning a decent profit.
What are some other basic security that I should be implementing into my site?
Conclusion
As you can see for the type of company I'm trying to launch it seems that security is very important. I'd absolutely love to hear any input and advice anyone has. Thank you to anyone who spent the time to read the full post!
I am creating a SPA blog website with PHP/MySQL and a Javascript frameworks, still haven't decided which one yet.
The idea is that I am willing to create an API and consume it using Javascript, but I want to protect the API, so that no one can access /posts/ for example and get a list of all the posts.
I am not requiring any registration and I don't have a users system.
How would I go about it?
Thanks
You might be able to hard code whitelisted IP addresses, but as Steve pointed out in the comments: it's either public or it's not.
I'd go with some little registration functionality that generates API-keys that can be used to access your API.
It has been pointed out that a public API is public, however there are some steps that could take to make it more difficult for consumers other than your UI to access it.
The problem is akin (though not the same as) Cross Site Request Forgery, and you can use a variation of any of the prevention techniques listed to mitigate unauthorized access to your API.
The simplest implementation might be something like this:
index.html
<?php
$mytoken = uniqid();
$_SESSION['token'] = $mytoken;
?>
<input type='hidden' name='apitoken' value='<?= $mytoken;?>' >
some-api-endpoint.php
<?php
if($_GET['apitoken'] !== $_SESSION['token']) {
header("HTTP/1.0 403 Forbidden", true, 403);
}
If someone wants to access your public API, they will be able to, but they will have to put forth at least a little bit of effort to do so.
Using a JWT service will work just as well.
Have a look here: introduction to JWT
You can also use an api key and secret which will be passed on initial session auth for your service.
Here's a Stackoverflow answer that helps explain what you'll need to do: key and secret in php
If you're really lazy, you can just use basic authentication or digest auth to auth on the client side. (This is not advisable and has security risks as if you're not using ssl the passwords are passed as plain text in the request)
Another article for your information: PHP HTTP Authentication
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
For my webapp (angular + node.js), I'm implementing a gamification system where users gain points for performing actions like answering questions, watching a video, etc. Currently, I simply post to '/api/users/updatepoints' with the user's id and number of points changed to update the database.
This is of course not secure, since a user could easily do an ajax request from the console while logged in, and I was wondering how I can prevent users from illegally sending out ajax requests? What sort of server-side validation could I use to do so?
//front end
$http.post('/api/users/updatepoints', {
kidId: xxx,
pointsChanged: yyy
})
//backend
exports.updatePoints = function(req, res) {
var kidId = req.body.kidId,
pointsChanged = req.body.pointsChanged;
User.findOne({_id: kidId}, function(err, user) {
if (err) return res.send(400);
user.points += pointsChanged;
user.save(function(err) {
if (err) return res.send(400);
return res.send(200)
});
})
}
The simple answer is "you can't".
A sufficiently determined hacker will always be able to take control of anything you are running on their computer. The only way to avoid that is to validate everything server side.
For example the only way to defeat "map hacks" in competitive online play is to never send information to the client unless that information is being displayed to the user.
If it's important, do it server side. Let the client side do its processing and validate and verify everything it sends you.
This is much too big a subject to properly discuss in a format like this though. Try doing some internet searches on preventing client hacks in games.