Jump to content

Jacques1

Members
  • Posts

    4,207
  • Joined

  • Last visited

  • Days Won

    209

Everything posted by Jacques1

  1. I think you should take a deep breath and get clear about what you want to do. It's not very helpful if you come back every 5 minutes, present some random idea, tell us that it works, then tell us that it doesn't work and start over with some new random idea. You've probably lost everybody by now. Try to approach this in a more systematic and thought-out way: What is the relevant data in the table? Is it I_ID? No, that's just the primary key. I'm pretty sure that I_PATH is the subdirectory of the main image directory, and I_FILE is the image file within this subdirectory. So the full path would be: https://yoursite.com/path/to/images/{I_PATH}/{I_FILE} I cannot verify this. If you're not sure either, ask the person who placed the pictures on the server. If this is indeed the correct path, now you need to write this down with actual PHP syntax.
  2. Well, you have tried it? What does it say?
  3. No. It tells PHP to interpret $this->price as a variable name: <?php $var_name = 'foo'; $foo = 'bar'; echo "${$var_name}"; // the same as $foo See variable variables. You need to escape the dollar sign, which is good practice anyway.
  4. Of course you can delete from multiple tables with a single query. You just need to get the syntax right, and the manual will be helpful for that.
  5. Besides the SQL injection vulnerability, your code is also vulnerable to mail header injections. This allows any user to send spam mails to arbitrary accounts and should get your IP address blacklisted pretty soon. So the Golden Rule of security applies here as well: Never trust user input. In fact, don't use the mail() function at all unless you have good reasons for that and understand the implications. If you just need to send a bunch of emails, you want a mailing library like PHPMailer. Regarding your original question: What have you tried? Do you generally understand how database joins work?
  6. No. Please look at the structure: You have three nested arrays. $arr has a single element, namely an associative array at index 0. This associative array again has a single element, namely a numerical array at key "a". And this numerical array finally contains the numbers. The number 10 is stored in $arr[0]['a'][9]
  7. Count the failed login attempts per user with the LAST_INSERT_ID() query above. Once the counter has reached a certain limit, the user must solve a CAPTCHA on every subsequent attempt. In addition to that, you should monitor the total number of failed logins. If this number gets exceptionally high, force all users to solve a CAPTCHA. But most importantly: Educate your users on choosing good passwords and using password managers. All login blocks are really just a band-aid to make weak passwords survive a little bit longer. They do not solve the underlying problem. The only actual counter-measure against brute-force attacks is to have a reasonably strong password.
  8. The point is that your IP checks are useless if the attacker simply keeps switching to new addresses. You're somehow assuming that everybody is limited to a single IP address. This is not the case. There are plenty of public proxy servers, there's Tor, there are botnets, there are Internet service providers which give their customers a fresh IP whenever they reconnect. Each of this provides an attacker with a large pool of different IP addresses they can use. Like I said, there's no shortage. So what exactly is the point of blocking one particular IP address if the attacker can simply switch to a different one? Even better for them: They can reuse all blocked addresses after 15 minutes. Combined with the various implementation errors I've already pointed out, this entire feature is useless. It may sound like a good idea, but it does absolutely nothing.
  9. This is even stupider. Look, there's no absolutely no shortage of usable IP addresses. Even the dumbest script kiddie knows how to reset their router, switch to a different HTTP proxy, use Tor or whatever. Now they got a fresh IP and can start over. And more advanced attackers have large botnets with thousands of zombie PCs. So this IP blocking thingy does absolutely nothing. Even worse: While you fill your IP blacklist, you increase the risk of accidentally hitting a legitimate proxy and locking out legitimate users. This is exactly the mistake I've described above when I talked about broken implementations. Then you haven't seen a lot of websites. But why does it matter, anyway? Shouldn't you worry about the effectiveness of a method rather than its popularity? I mean, you can do whatever you want. If you think that half-working IP blocks are totally great, go ahead. But in my opinion, this is bullshit.
  10. Click on the link, it's all explained there.
  11. I really don't know what you're trying to do with that URL parameter. No, you cannot magically execute SQL queries through the URL. This would obviously be a security nightmare. Just pass the range information to the script. This is as simple as using a from and a to parameter. Those two parameters also have the nice side-effect of allowing users to specify custom ranges.
  12. That small code snippet doesn't tell us anything. Could be an issue with the query to fetch the pending mails (which we don't know), could be an issue with your server configuration (which we don't know), could be an issue with your PHPMailer version (which we don't know). Make sure you got an up-to-date version of PHPMailer (5.2.7). Then run the script a couple of times and send yourself some emails to see if you can reproduce the problem. If you can, var_dump() will help you analyze the exact conditions.
  13. Well, then you should have asked for that rather than taking a detour in the hopes that it will somehow lead to the solution. The first thing you should do is set an application-specific save path for the sessions. If the sessions are stored in some generic folder like /tmp, then you never know which process is deleting the files based on which criteria. Then you need to check if the settings are working correctly. If you stick to a lifetime of 1440 seconds, when exactly do the sessions get cleaned up? Before 24 minutes? Exactly after 24 minutes?
  14. This account locking stuff is highly questionable, as popular as it may be. First of all, you now have a gigantic denial-of-service vulnerabity: Anybody can lock out arbitrary users simply by constantly sending wrong passwords. If an attacker does this a couple of times, you'll soon have no users at all. Secondly, this feature creates a false sense of security. If the password is so incredibly weak that it won't even survive a primitive online attack, then it won't survive any attack. The first database leak will immediately reveal it, no matter how well it has been hashed. It makes much more sense to solve the actual problem and educate the users on choosing better passwords. Third, an attacker can easily circumvent the check by trying one password on many accounts instead of many passwords on one account. And last but not least, every single implementation I've seen so far was wrong (including Sinan's link above). They all make the same mistake: They count the current number of failed login attempts. Time passes. They increment or reset the counter. Well, what if I make hundreds of concurrent requests between step 1 and step 3? Then the script always checks the old counter value and will accept any number of attempts, When the counter is finally incremented, it's already too late. The counter must be incremented and read in a single atomic operation: UPDATE users SET failed_login_attempts = LAST_INSERT_ID(failed_login_attempts + 1) WHERE user_id = 1 ; The new counter value can then be fetched with LAST_INSERT_ID(). But again: The whole idea doesn't make a lot of sense. If you absolutely must have this, because your boss or your users demand it, then at least don't lock the account but rather force the user to solve a reCAPTCHA on every subsequent attempt. This also slows down the attack and increases its costs (literally), but it doesn't have this devastating effect on legitimate users.
  15. So you've tried all kinds of things, but it never occured to you to simply check the MySQL manual for how the syntax of a SELECT statement actually looks like? The ORDER clause comes after the WHERE clause. You also seem to have some loose parentheses in your ORDER clause.
  16. That wikiHow article is, again, a good example of how not to do it. Why do you want to store the sessions in the database? Why do you think this makes you more secure? I strongly recommend that you do not do this. Handling sessions is much harder than you may think. For example, you now have to worry about concurrency issues: Process A and process B both read a variable of the same session, say amount with a current value of 0. Process A increases amount by 100, process B increases it by 200. Common sense tells us the result should be 300. But it's actually 200, because B has overwritten the update of A. How do you prevent this? The standard PHP sessions already take care of those ugly little details. But if you implement your own session handler (or steal it from some crap website), then you're suddenly confronted with all kinds of problems you probably haven't even thought about yet. So, just stick to the standard. There are much worse security issues, anyway: Why on earth do you store the user password in the session? The passwords are sensitive data. You must protect them, not throw them around in some temporary files. What is that supposed to do, anyway? You store the passwords as plaintext? Seriously? Again: The passwords are sensitive data. You need to hash them with a strong algorithm like bcrypt. Your code is wide open to SQL injections through the password parameter, because you drop $_POST['password'] right into your query. Your whole escaping strategy is rather questionable. What is your clean() function supposed to do? “Clean” for what? Do you really still have magic quotes turned on? I thought that stuff died somewhere in the 90s. The mysql_* functions you're using are obsolete since more than 10 years and will be removed in one of the next PHP releases. Nowadays, we use PDO. This will also help you solve your injection vulnerabilities, because the new database extensions support parameterized queries. In my opinion, IP checks are bullshit. But that's another story, I guess. So before you do the fine-tuning of your security, please fix the gaping holes.
  17. You're checking the result variables before you've even fetched a single row. How is that supposed to work? What are $id, $word and $def supposed to contain before the first mysqli_stmt_fetch() call? You first need to fetch a row. And then you can check the content of this particular row. Besides that, this looks like an awful lot of code for such a trivial task. The first thing you should do is get rid of all the manual error checks and simply have MySQLi throw an exception whenever something goes wrong: // do this before you establish a database connection $mysqli_driver = new mysqli_driver(); $mysqli_driver->report_mode = MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT; Then delete all the useless mysqli_stmt_store_result() calls. Not sure what that is supposed to do in case of an UPDATE query. Why you're trying to rollback an update query when it has no affected rows is also beyond me. What is there to be rolled back then? And what's the problem with zero affected rows, anyway?
  18. This simply makes no sense. It seems you misunderstand how HTTP and HTML works. An HTTP response contains a single resource with exactly one type: You can either send an HTML document or one(!) image, but not HTML mixed with multiple images or something like that. If you want to use images in HTML, you need an img element with a URL pointing to the image content: <img src="https://yoursite.com/images/cute_kitten.jpg" alt="cute kitten"> The image source may very well be a PHP script which outputs the image data dynamically: <img src="/admin/getImage.php?id=1234" alt="some sensible description"> I guess that's what you want. The getImage.php script would take the image ID from the URL and output this particular image.
  19. Sending some fancy country name string to the form processing script makes no sense. The point of the form value is to uniquely identify the chosen country. So use the country ID or the alpha-2 code or the alpha-3 code or any other unique identifier. Then check if this identifier exists in your database: -- check if the user-chosen value "HR" exists in the database SELECT 'HR' IN ( SELECT alpha_2 FROM countries ) ;
  20. What is the problem? We can't see your screen from here, you know? If you want help, you need to actually tell us what you see. Otherwise, you'll have to do this on your own. I'm not gonna play error guessing.
  21. Well, “some difficulty” isn't exactly the most specific error description. So what's the problem? And what's the loose parenthesis doing there? $_POST(['sexType']
  22. Setting the same header multiple times does not lead to conflcts. The only reason why you're getting an error message is because you have output before the second header() call, which is not allowed. Looks like you've forgotten the CURLOPT_RETURNTRANSFER.
  23. You need a cron script which runs at the desired times. You also need an HTTP library like cURL to make the requests. Your script first sends your credentials to the login page and gets back a session cookie. Then you request the file while including the session cookie. The manual will tell you how to use cURL. Note that using automated scripts may violate the terms of use.
  24. Changing data based on a plain GET request is wrong and a very bad idea. For example, I could delete all student records simply by publishing a bunch of images with URLs like http://yoursite.com/Admin_Edit_Student_Info.php?id=1. If any admin visits this page, they immediately trigger the DELETE query without even realizing it. For extra fun, people can inject malicious JavaScript code through the id parameter and steal the session ID of the admin or show them a fake login page to get their password. This is hardly a “solution”, not even by the lowest standards. A proper approach would look something like this: You need to escape all user input with htmlspecialchars() before you can insert it into the HTML document. To change data, you need to use a form with the POST method. If you want a robust solution which works without JavaScript, add a hidden field named something like confirmed to the form when the user confirms the message. When that field is missing in the request, you know the user doesn't have JavaScript turned on, and you can fallback to plain HTML. Now is the right time to start thinking about cross-site request forgery. <?php $use_fallback_confirmation = false; if (isset($_POST['action']) && $_POST['action'] == 'delete' && isset($_POST['student_id'])) { if (isset($_POST['confirmed']) && $_POST['confirmed']) { echo htmlspecialchars('Deleted record of student ' . $_POST['student_id'], ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); } else { // JavaScript seems to be turned off. $use_fallback_confirmation = true; } } ?> <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title>A form with confirmation</title> <script src="http://code.jquery.com/jquery-1.11.1.min.js"></script> <script> $(function () { $('#delete_student_record').submit(function (event) { if (confirm('Do you really want to delete the student record?')) { $(this).append('<input type="hidden" name="confirmed" value="1">'); } else { event.preventDefault(); } }); }); </script> </head> <body> <?php if ($use_fallback_confirmation): ?> Do you really want to delete the student record? <?php endif; ?> <form id="delete_student_record" method="post"> <input type="hidden" name="action" value="delete"> <input type="hidden" name="student_id" value="1"> <?php if ($use_fallback_confirmation): ?> <input type="hidden" name="confirmed" value="1"> <?php endif; ?> <input type="submit" value="Delete student"> </form> </body> </html>
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.