Jump to content

DavidAM

Staff Alumni
  • Posts

    1,984
  • Joined

  • Days Won

    10

Everything posted by DavidAM

  1. I agree that the error message should only be displayed in development. So escaping it should not strictly be necessary. Escaping it for mysql (mysql_real_escape_string) would not be the correct escaping for it in any case. However, if the query contains HTML markup being written to the database, and the query failed, and you don't escape it using htmlspecialchars or htmlentities, then it could be difficult to read and interpret the error message. Again, however, this is information only for the developer and you can always see the raw output using the View Source feature of the browser. If you setup so errors are displayed during development and logged during production and you use trigger_error to display/log the mysql error, you would not want to escape it when it is logged. My suggestion would be, don't bother escaping it, at all. If, during development you get a displayed error that looks strange, use View Source to see it in the clear. If you do escape it, then you have to first check whether you are displaying or logging errors, so you can escape it or not. That would be a waste of programming time and execution resources. As for the security risk of user injections; again, you are only displaying it during development; so unless you are testing XSS injection attacks, you are not likely to run into any security issues. Not entirely true. The sanitation for the database is different from the sanitation for HTML display. Neither one provides protection for the other.
  2. You need to anchor it to the beginning of the string WHERE username RLIKE '^[SPN]'
  3. It sounds like you are asking how to not write the visitor's IP Address to the second file if it is already there. This would be a simple matter except for the fact that you are appending the counter to the IP address, why is that? Anyway, without the counter added, it would go something like this: $ip = $_SERVER["REMOTE_ADDR"]; if (file_exists($File2)) $ipList = file($File2, FILE_IGNORE_NEW_LINES); else $ipList = array(); if (!in_array($ip, $ipList)) { file_put_contents($File2, $ip . "\n", FILE_APPEND | LOCK_EX); } If you really need/want the :$counter appended to the IP Address, you will have to walk the array ($ipList) and compare the IP address part with the user's IP address. If you get through the entire array and don't find the user's IP, then you would add it. Note: the code above requires PHP 5.0 (for some of the flags). Note: Using file storage like this is not best practice. You are single-threading through the file, which means if multiple users hit the code at the same time, they will have to wait for the others to complete. Also, if two users from the same IP address read the file at the same time, and neither finds their IP in the file they will BOTH add it, causing duplication. You can attempt to use fopen, fread, fwrite, and fclose, to keep the file locked, but again that leads to delays for the user. This type of thing is best done with a database.
  4. Yeah, I'm a very literal person, and that's the way I interpret the words. According to the manual, it used to use access-time; but now uses modification time. I have an in-house app that uses sessions. When I wrote it, I did not consider the distinction. Sometimes, I can use it all week without having to login again. Sometimes, I have to login twice in the same day. It all depends on how much use the app gets, since garbage collection is only considered when session_start() is called. My only experience is with Apache. I cannot speak to how others handle it. However, these settings are controlled in PHP, so I would think it applies across the board. Wherever the session files are written, the directory MUST be readable and writable by the (system) user that the web server runs as.
  5. Oops! I misspoke. It is not a nonce, it is just a unique token. A "Remember Me" (in my book) just remembers and fills in my login name on the login form. It is different from a "Stay Logged In", which actually authenticates. However, I rarely use the "Remember Me" because on most sites, it is not clear if they are using it to "Remember Me" or to Keep me Logged In (which I don't want, most places). The garbage collection uses the file's last modification timestamp to determine how old the file is. So the session data ages unless you actually modify/update the session data. It is a security issue, especially on a shared host. The default is to write the files to /tmp which is WORLD READABLE. So anyone who has or gains access to the server can read the session data - it is NOT encrypted.
  6. This bears repeating. Even if you set the COOKIE expiration to a year, you can NOT be sure the SESSION data ON THE SERVER will survive that long. Unless you are using a CUSTOM session handler, session.gc_maxlifetime controls how long the session data file survives. If you try to change the session lifetime, you have to change it for ALL SCRIPTS using SESSIONS at the session.save_path of your site. If you are going to use a custom session handler to get around this issue, then you may as well use a standard COOKIE (not the session one) and handle the extended expiration in the custom session handler. The other solution I see, is to leave the standard session cookie alone, and add a second cookie for "Stay Logged In". When you get a request with a "Stay Logged In" cookie (and no active session), you lookup the nonce in the database to identify the user and start a new session (just as if they had logged in). Yes, this effectively reduces the login from two tokens (username and password) to a single token (the nonce), but that is the choice you and the user make when implementing/using this system. You could carry a flag in the session that indicates you don't have a real authentication from the user, so if they try to do something critical (i.e. change their password), you can require them to authenticate by entering their existing password. I don't recommend this (Stay Logged In) for highly sensitive sites, because it is not highly secure. There is a reason you don't see "Stay Logged In" at your Banking sites. And, for the record, the nonce in the "Stay Logged In" cookie is NOT the user's password (hashed or otherwise), it should be (IMHO) a hash generated specifically for that purpose. (And, of course, it must be unique in the database).
  7. Self-documenting code. list($key,$value) = explode("\t", $dataLine, 2); // more code here ... $dataOut[$key] = new clsSomething($value); is easier to read and understand (by a human) than $data = explode("\t", $dataLine, 2); // more code here ... $dataOut[$data[0]] = new clsSomething($data[1]); particularly if $dataLine has more than 2 elements, and you are manipulating those elements in some way in the // more code here ... section. I think this is the only time I ever use it.
  8. I wouldn't have thought that valid code, but apparently it is. I'm not sure which of the following is the problem, but I suspect that: 1) You need "()" after the classname: new $this->_url[1](); 2) You need to adjust the binding with curly-braces: new {$this->_url[1]}(); 3) Try putting the classname in a variable instead: $class = $this->_url[1]; $this->_adminController = new $class();Let us know which one fixes it.
  9. SELECT `desc`, COUNT(*) FROM table1 JOIN table2 ON table1.pid = table2.pid WHERE table2.cat IN (101, 102) GROUP BY `desc` HAVING COUNT(*) = 2 Anything that belongs to either 101 or 102 - but not both - will have a COUNT of 1 and will be excluded by the HAVING phrase. Note: this will return entries that belong to 2 or more categories as long as two of them are 101 and 102.
  10. You are referencing $data if the file does not exist so $data has not been defined. You are using globals which is a real no-no. You have repeated code. And you are processing a file at times you don't need to. Could we get this to "work"? Yes. But if you ever need to add a server (for scores or mirrors), you will have to rewrite the entire thing. Try this: <?php ini_set( "display_errors", 1); //hide fsockopen/fopen warnings if file doesn't exist or couldn't connect define('C_STATUS_FILE', 'status.txt'); // Status File Path define('C_STATUS_AGE', 30); // Seconds to cache server status // List of interesting servers $servers = array('Game' => array('IP' => "178.175.141.27", 'Port' => "7777", 'Status' => 0), 'Login' => array('IP' => "178.175.141.27", 'Port' => "2106", 'Status' => 0)); /* Check to see if a particular server is online Returns (int) 1 for YES and 0 (zero) for NO */ function IsOnline($paServer) { $sock=@fsockopen($paServer['IP'], $paServer['Port'], $errNo, $errStr, 3);//timeout set to 3 seconds if($sock) { fclose($sock); return 1; } return 0; } /* Get the status of all servers The server array is passed by reference and is UPDATED If the status cache file exists and is less than C_STATUS_AGE seconds old, we read it; otherwise we try to connect to each server and update the status cache file. */ function RefreshStatus(&$paServers) { if ( (file_exists(C_STATUS_FILE)) and (filemtime(C_STATUS_FILE) < time() - C_STATUS_AGE) ) { $paServers = unserialize(file_get_contents(C_STATUS_FILE)); return; } foreach ($paServers as $name => $data) { $paServers[$name]['Status'] = IsOnline($data); } file_put_contents(C_STATUS_FILE, serialize($paServers)); } // Get the server statuses and output the table RefreshStatus($servers); echo'<table width="100%" cellspacing="0" cellpadding="2">'; foreach ($servers as $name => $data) { if ($data['Status']) { $color = $wincolor; $status = 'ONLINE'; } else { $color = $loosecolor; $status = 'OFFLINE'; } echo '<li style="background-color:' . BG_1 . '"> <strong>' . $name . ' Server:</strong> <span class="result"><font color="' . $color . '">' . $status . '</font></span> </li>'; } echo'</table>'; I changed the status file format, so delete it before your first run. The code uses an array to hold the server data, so you can add other servers (later) in there if necessary without changing any of the other code. The RefreshStatus() function uses the file-system timestamp rather than a value in the file. This way we don't waste resources opening and reading a file we don't need. The data is stored as a serialized array ($servers) so we can just read it and unserialize instead of trying to parse it. There should probably be a check that if the unserialize fails (because the file is corrupt), it will goahead and check the servers and write a new file. I stripped down your output. There was no real difference between the two servers, so we put it in a loop. Now, if you want to change the output format, you do it only ONCE and all servers are done. Note: the first thing you should do is get rid of the (deprecated) FONT tags. I have not tested this, so there might be some typos. But read through it, and try to understand it.
  11. Something like that. You don't need a lot of PHP for this, either. You can update ALL of the pending games in a single SQL statement. Something like (untested): UPDATE playersTable p1 JOIN playersTable p2 ON p1.idGame = p2.idGame SET p1.Winner_report = p2.Winner_report, p1.Winner_report_timestamp = NOW(), p1.Game_status = 4, p2.Game_status = 4 WHERE p1.Winner_report IS NULL AND p2.Winner_report IS NOT NULL AND p2.Winner_report_timestamp <= DATE_SUB(NOW(), INTERVAL 24 HOUR) I'm not sure that is the best database design, but not seeing the other tables and not knowing the application, I can't say for sure. You also need to think about a cron job to report (to you) any contested matches. For instance, if Steve comes along and says HE won the game (or maybe you already handle that in the front-end).
  12. What would the script do? If all you want to do is consider the report "true", then when you select from the database, the report is "true" if the timestamp is older than 24 hours and user2 did NOT mark it "false" (reject). If you need something to happen. You can schedule a cron job to run periodically. The cron job would do whatever needs to be done, under the same conditions (timestamp > 24 hours and user2-response != Reject). How frequently you run this cron job depends on how time-critical the "something" is. If you run it every 24 hours, then it will find events anywhere from 24 hours to 47 hours 59 minutes. If you run it every hour, it will find events anywhere from 24 hours to 24 hours 59 minutes. Be sure that the "something" being done includes updating the row to indicate it has been processed.
  13. Barand is correct, the values in the IN phrase need to be integers, not a single string. As it is, the COUNT(*) will return 1 because the database server will convert the string to an integer and look it up. ALSO, if you are using PHP to get the number of rows returned by the query, THAT value will ALWAYS be 1 (even if there are NO MATCHES). SELECT COUNT(*) ... will return one row containing the count. The count may be 10,000,000,000,l00; but there will only be ONE ROW returned. Make sure you are fetching that row and retrieving the value of the first column ("count_result").
  14. Now Doc (emphasis added) Try it without the single quotes (Here Doc) $body = <<<EOT $email_message EOT;
  15. This forum updates my profile (Last Active Date-Time) on every page view. It also updates each Topic I read (Number of Views). In fact, the bottom of this screen says it executed 15 Queries to show me this Topic. A single well written insert to the database for every page view should not be too taxing. On the other hand, writing the code to actually analyze the data could be a chore (for the programmer, I mean). Google has done it, why re-invent the wheel (unless you need too).
  16. In general, everyone in the same house or the same office will have the same public IP so, blocking by IP only allows one vote per gateway. Cookies can be removed by the user, so that is not dependable. Besides, i could vote with Firefox, then with I.E., then safari, ... every browser has its own cookie jar. Requiring a login is the only way to restrrict -- and that's only by login, if users can register with different credentials, then they can vote multiple times. The only sure way to restrict is to have an ironclad registration and login system.
  17. See my comments in this copy of your code function myFunction(str) { document.getElementById('div_textarea').innerHTML = ""; loadXMLDoc(str, function(){ if (xmlhttp.readyState==4 && xmlhttp.status==200) { document.getElementById('div_textarea').innerHTML = xmlhttp.responseText; /* MAD Why do you not just call button_onload() here? This is the only place where you know for sure that the elements have been put into the DOM */ } }); //button_onload(); /* MAD This code may execute BEFORE the AJAX completes. It WILL execute even if the AJAX FAILS. I would put this inside the IF statement above -- withOUT the setTimeout() */ setTimeout(function(){ button_onload() }, 100); } Also, are you sure that there are NO OTHER ELEMENTS with the ID attribute set to "button", "button2" and "button3"? The ID attribute MUST be unique throughout the entire document. I really see NO benefit in the button_onload() function. Why not just set these values in the PHP script. There is no real reason to use PHP for index and index2. You could just output the plain HTML. Of course, if you want to reuse code, I guess that is one way to do it. Depending on the application, I would probably just pass a parameter in the URL indicating what labels I want and let PHP set them accordingly. Is this really all of the code? I really don't understand why you are doing it this way.
  18. See http://en.wikipedia.org/wiki/Cross-site_scripting - If you display user submitted text without "escaping" for HTML special characters, you are at risk. Well, that's one thing already done. Neither do I, but what else is there? Spammers may capture the page and store it locally, then have separate processes that submit the page with spam. In this case, your timestamp can be VERY OLD. Bots can submit a different value for a hidden field than the value provided by your script. if the field has a name of "loadtime" and the value looks like a timestamp, the bot may just plug in a current value to get around the (obvious) timecheck. I have also heard of people adding a regular text field with a "tempting" name (such as URL, or WebAddress), which a bot is likely to stick a link in. The developer has made this field display: none using CSS. Bots are not likely to interpret CSS and will not know the field is not "visible". Since it is not visible to live people, it should never contain a value when submitted. I have heard, though I never confirmed it, that there are actual sweat-shops that pay people to spam sites. Of course, CAPTCHA will not be effective in that case either.
  19. w3schools != w3c There is no relationship between the website named w3schools.com and the w3c. "The World Wide Web Consortium (W3C) is an international community where Member organizations, a full-time staff, and the public work together to develop Web standards." http://www.w3.org/Consortium/ "At w3schools.com you will learn how to make a website. We offer free tutorials in all web development technologies." w3schools.com In the past there have been many reports of inaccuracies on the w3schools site. I don't use it, and I don't know what strides (if any) they have taken to correct the issues. But, you should remember, they are NOT associated with the Consortium that develops the standards and specifications; and therefore, their site is based on their interpretation of the standards.
  20. Then ALL emails will contain ALL of the email addresses you are sending to. Effectively giving everyone on your email list a list of valid, active email addresses (so they can spam their hearts away). It really depends on the application. But if I register at a website, and that website distributes my email address in their email blast, I will be very upset. Heck, I get upset when my sister sends jokes and such to everyone in her address book (I finally convinced her to use a distribution list system). Depending on your audience -- For in-house stuff, I do use multiple names in the TO header, of course everyone at the office already knows everyone else's address -- For a "Family" site, I might consider it, but heck, there are people in my family that I don't want to have my email, or I intentionally give them a different address from the ones I actually like. If this is for a "real" website, your best bet will be to use a queue system or a real list service. Depending on your host, there is likely to be a limit on the number of emails you can send per hour. Jazzman1 - my response was to the OP's failure to try/fix the one spot I identified as the problem. It was not a shot at your solution. As above, your solution will work and I have used it.
  21. No Protection!? Risks SQL Injection - Submission of SQL statements that are executed by your database - Database Loss, Data Retrieval, etc. XSS Injection - If you display this data you are subject to Cross-Site-Scripting injections - negative impacts on your visitors SPAM Submissions - Submission of junk posts into your database Any of these attacks can be submitted by Bots and by Humans. SQL Injection - Escape all user input before sending to the database - Depending on your database server, see mysql_real_escape_string, or escapaing function specific to your database engine XSS Injection - htmlspecialchars to prevent HTML from being interpreted by the browser SPAM Submissions - CAPTCHA or other gatekeeper to help prevent BOT submissions
  22. It is better to use a JOIN. It is also better to select ONLY the columns you need (don't use SELECT *). SELECT projectId, projektName, projectDescription, statusName, userName FROM Projects JOIN ProjectStatus on Projects.statusId = ProjectStatus.statusId JOIN Users ON Users.userId = Projects.userId I'm just guessing at some of the column names, since you did not show all of the columns in the Projects table.
  23. That's probably ... Oops, I guess I missed it in the initial post: Random connection errors could be caused by overloading the database server. Make sure you only connect to the database ONE TIME per page request (script). Do not OPEN and CLOSE and OPEN and CLOSE .... the connection. It takes a little while for the connection to completely go away, so you could be reaching the connection limit for the server. However, I don't understand why the printed message "Changed database context to 'databasename'", would be intermittent. I would expect that would happen every time; unless ... Are you using persistent connections? I hope someone with actual MSSQL experience comes along to help more.
  24. At the risk of repeating myself: * Line numbers may have changed, I didn't bother to check The function mail is the one that SENDS emails. Since it is NOT IN THE LOOP it is NOT GOING TO SEND FOR EVERY RECORD FROM THE DATABASE. You even have a comment INSIDE OF THE LOOP that says //send email. That is where you need to, uhh, send the email!!
  25. You need to structure your code, with proper indenting, so it is easier to follow. Also, turn on error reporting while in development, so you can see any error messages. Put this at the very beginning of your script. error_reporting(E_ALL); ini_set('display_errors', 1); Here is your code, with line numbers and proper indents: <?php session_start(); //allow sessions include("config.php"); //get database information if(!$_POST[send]){ //if the form was not submitted echo "<form action='' method='post' > <table width='600' border='0' cellspacing='0' cellpadding='0' align='left'> <tr> <td height='35' colspan='2' align='left'><b>Send a email to all users</b></td> </tr> <tr> <td height='35' align='left'><b>Subject:</b></td> <td width='515' align='left'><input type='text' name='title' id='title' size='30' /></td> </tr> <tr> <td width='85' height='150' align='left' valign='top'><b>Message:</b></td> <td align='left' valign='top'><textarea name='msg' id='msg' cols='65' rows='9'></textarea></td> </tr> <tr> <td height='35'> </td> <td><input type='submit' name='send' id='send' value='Send' /></td> </tr> </table> </form>"; //return with the form }else{ //or if it was $supportEmail = 'support@mysite.com'; $title = strip_tags(htmlspecialchars($_POST[title])); $date = date("F j, Y, g:i a"); $values = array(); $message = stripslashes($_POST[msg]); //message $getusers = mysql_query("SELECT * FROM user"); $getemail = "SELECT email FROM user"; $result = mysql_query($getemail); $to=$row['email']; $link="<a href=\"http://mysite.com/contact.php\">Click here</a>"; if(empty($message)){ echo "<a href=\"history.go(-1)\">Go Back</a>You Can Not Send An Empty Message!"; }else{ while ($row = mysql_fetch_array($result)){ $email = $row['email']; //send email } $body = <<<EOD <br><hr><br> =============================== <br> <br> Subject: $title <br> Message: $message <br><br> This message has been sent by My Site. Do not reply to this email. $link to contact support. <br> =============================== <br><br> EOD; $headers = "From: $supportEmail\r\n"; $headers .= "Content-type: text/html\r\n"; $send_contact = mail($email,$title,$body,$headers); // Check, if message sent to your email if($send_contact){ echo "<script language='javascript'> alert('Your site wide email has been sent.'); window.location.href = 'http://mysite.com/x9y6uw5e8_/admin_panel.php?page=mass_email'; </script>"; } } //end check for empty message } //end form check Line 5: This should be producing a warning or two. I would change it to if (! isset($_POST['send'])) Line 29: $values is defined but never used. Line 30: You don't need strip_slashes here unless magic_quotes_gpc is on (and it should never be on). Line 31: You execute a query here, but never use the results. This is a complete waste. Line 35: You are trying to get the email address from $row but it is not defined. Line 38: You should check for this before you bother executing the query. Lines 41 - 45: HERE IS YOUR PROBLEM. You are walking through the result (list of email addresses) but you are not sending the email in the loop. So, nothing is getting sent. Lines 47-71: This code would send the email, but it is outside the loop. So, if it is sending any emails, it is sending ONLY to the LAST address retrieved from the database. You really need to restructure this code: <?php // SETUP - Error reporting, session, config // POSTED? - If the form was posted, process the user input // Check ALL fields for valid data: title, msg // VALID DATA? - If the data is valid, send the emails // Build the "constant" (common) portions of the email (headers, body, from, etc) // Issue the query and loop through the results // For each row, build the email and call mail() to send it // Keep track of any failures // End loop // Compose a success message // ELSE - Data is not valid // Compose an error message // ELSE - Not Posted // Show the success or error message (if present) // Show the form
×
×
  • 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.