Jump to content

DavidAM

Staff Alumni
  • Posts

    1,984
  • Joined

  • Days Won

    10

Everything posted by DavidAM

  1. Glad to help. On the injection attacks, you should be able to find several postings on the forum that cover it. But let me give you an example. Since you are adding additional headers that contain a field the user enters, we will start with $email. If I enter the following as my email address: Innocent@victims.net>\nTo: victim1@victims.net\nTo: <victim2@victims.net your $headers will read: From: SenderName <website@server.org>\nReply-To: SenderName <Innocent@victims.net>\nTo: victim1@victims.net\nTo: <victim2@victims.net>\n which causes copies to be sent to victim1 and victim2. Of course, then I type some kind of Viagra message or something, NOT a prayer request. If you try to track down the sender, you find Innocent@victims.net, who is obvisouly NOT the spammer. If I change "To:" to "BCC:" your Pastor or Prayer Minister will not even know that the message went to others. He will be getting spam from his own site and will not know why. At the very least, you should reject any posting that has a newline (\n) in the email address. It is not a valid character for an email address and there is no reason for your target users to be entering it. I am no expert on injection, so I am sure that there are other issues to look for, this is just an example. $to and $subj are hard-coded in your script, so they seem to be pretty safe. $body may need to be modified slightly. Some older mail processors may interpret your first lines as another header because they look like headers (starts with the word From: in the first position followed by a space). I would add a text line at the top of $body just to be safe. Something like: $body = "A prayer request has been submitted at the website\n\nFrom: $name\n E-Mail: $email\n Message:\n $message\n $check_msg"; Also, the mail() function has four parameters. I don't know where $sent is coming from, it is not defined in your code (that I can see), but it should not be in the function call. Once you get it online, you can go to the Website Critique forum and post a topic asking people to review it. There are those who will try various attacks and let you know what succeeded and how to fix it. You might want to have the messages going to you and not the Pastor during the test (unless you want him to know how difficult this can be).
  2. If the checkbox is not checked, then it does not get posted. So, you have to check to see if it is there before processing the array. <?php //$value = $_POST['check']; // THIS LINE CAUSES AN ERROR IF NOTHING IS CHECKED $to = "myemail@gmail.com"; $subject = "Prayer Request Form"; $name = $_REQUEST['name'] ; $email = $_REQUEST['email'] ; $email1 = $_REQUEST['email']; $message = $_REQUEST['message'] ; $headers = "From: $name <website@server.org>\nReply-To: $name <$email1>\n"; // Right here - check to see if any checkboxes are checked $check_msg = ''; // ASSIGN an empty string so we don't get an error referencing it later if (isset($_POST['check'])) { // CHECK TO SEE IF ANYTHING IS CHECKED foreach($_POST['check'] as $value) { $check_msg .= "Checked: $value\n"; } } // END IF (isset($_POST['check'] $body = "From: $name\n E-Mail: $email\n Message:\n $message\n $check_msg"; if (mail($to, $subject, $body, $headers, $sent)){ echo "Your prayer request form has been successfully submitted."; }else{ echo "Your prayer request form has been unsuccessfully submitted. Contact an admin or try again"; } ?> Note: There are other issues you need to address. 1) Replace $_REQUEST with $_POST -- $_REQUEST looks in $_GET, $_POST, $_COOKIES for the array element. Which means I can spoof your form very easily. You were using $_POST in your original post, so go back to it. 2) You MUST sanitize the values that are coming from the user. Even if you switch to $_POST, you still need to prevent injection attacks and to prevent spammers from using your form to send out tons of garbage.
  3. Well, excuse me for not mentioning the $_POST vs. $_REQUEST issue. I guess I was tunnel-visioned on helping the OP SOLVE HIS PROBLEM. I am not a Doctor, I didn't even stay in a Hotel last night. Disclaimer: Nothing in this post, or any other post, provided by me in this forum, or any other forum, whether on this website or any other website, whether quoted by some other individual, company, administrator, hacker, tracker, trucker, or sleeper, does not imply approval of or dis-approval of the way the original poster, or any respondent to the original poster, or any respondent to any other respondent, coded, tested, tried to code, failed to test, held their head, feet or hands during their post, or any particular function, feature, setting, or expression, used in the post or suggested by the post or omitted from the post. No warranty is expressed or implied by me posting or failing to post on this site or any other site. Anyone reading my post in whole or in part, including but not limited to reading my mind, accepts full responsibility for any action they take or fail to take and the results, lack of results, or phase-shifting that may occur.
  4. You assigned a REAL name to the From: header. Your server "assumes" that the name you supplied is a local mailbox and adds your server's address. So specifying "From: Frank" you end up with "From: Frank@myserver.com" However, that does NOT generate a VALID email address for the From: header. If you are wanting to show the submitted name in the inbox list, you can assign the value to be displayed by formatting the header as: From: Real Name<website@myserver.com> (where website@myserver.com) is a valid email address for the server. Be aware that if the person reading the message hits REPLY, it will send to that address (which is not the person who submitted the prayer request). So add the Reply-To header I mentioned before: Reply-To: Real Name<theirEmail@theirserver.com> so you end up with something like this (UNTESTED CODE) $to = "myemail@gmail.com"; $subject = "Prayer Request Form"; $name = $_REQUEST['name'] ; $email = $_REQUEST['name'] ; $email1 = $_REQUEST['email']; $message = $_REQUEST['message'] ; $headers = "From: $name" . <website@webserver.com>\nReply-To: " . $name . "<" . $email1 . ">\n"; By the way - and this is IMPORTANT - you really need to sanitize the user input before putting it in the email like that. If you are not doing so, you are setting yourself up for XSS attacks and so forth.
  5. You are basically talking about faking the From address of the email. Most servers will not allow this. Your server may refuse to send the message because the email address it is stated to be coming from does not belong to the server (it was forged). Other servers may refuse to deliver the email for the same reason. One way to work around this is to add an additional header called: ReplyTo (or maybe Reply-To, I can't remember if it has a dash or not). The mail() function allows a fourth parameter for additional headers. The email clients that I have used will use this address when the receiver chooses to send a reply to the message.
  6. The error message does not mean that the header() function must be the first line of code. It just has to be executed before any output is sent (to the browser). Output is sent when you call echo, print() or other functions that send information. If an error occurs and error_reporting is on, errors are sent to the browser. Anything, ANYTHING including blank lines or spaces that are outside of the php tags (<?php ... ?> or <? ... ?>) is automatically sent to the browser. Check everything above the code that is calling the header() function. Also check all included files. One common cause is when there is a line-feed (or carriage-return) after the last closing tag "?>" in an included file. A common solution to this, is to just not include the closing tag in the included files. You'll have to decide for yourself whether that is a hack or not. Also make sure there is NOTHING BEFORE the first opening php tag.
  7. If you write an array like that, you get the word "array" as output. Since $results is an array of lines, you will need to use a loop to write it -- something like this: foreach ($results as $line) { fwrite($fh, $line); } Depending on whether or not the line-feeds are still on the lines after input, you may have to add them to the output. If you try the above and everything is on one line then change the write to: fwrite($fh, $line) . PHP_EOL; You might be able to write it with a single command (getting rid of the fopen() and fclose() calls) by using file_put_contents(). Take a look at the PHP documentation http://us.php.net/manual/en/function.file-put-contents.php
  8. That is an indication that the query failed. There could be a syntax error. Try a couple of things: 1) Modify the SQL to use the table aliases in the WHERE clause: $query= "SELECT P.*, COUNT(C.*) AS CmtCount FROM pictures P LEFT JOIN pic_comments C ON P.picid = C.picid WHERE P.album = $albumid AND P.status = 'Approved'"; 2) Right after executing the query, check the result and show the error and the SQL: $result = mysql_query($query); if ( $result === false) { echo mysql_error(); echo '<BR>' . $query; } we can work on any errors revealed by #1 above. In any case, you'll need to change this line: $CmtCount = $k; to this: $k = $row['CmtCount']; By the way, are you getting warnings about these lines: $thumb = $row[thumb]; $picid = $row[picid]; $path = $row[pic_path]; $caption = $row[caption]; $posted = $row[submited_by]; because, unless you have "thumb", "picid", etc defined as constants they should be in quotes. If you are not getting warnings, you should turn on error reporting at the beginning of every page during development so you can see any problems that are reported: error_reporting(E_ALL);
  9. I don't know why you have the while($_POST) inside that loop. It will always evaluate to true, so you are doing the update for the first POST key over and over again; that's why you got the execution time error. Remove this while loop, and I think it is doing what you want.
  10. Your second query ($query6) is completely unnecessary; and you are wasting resources bringing all the comments back and just looking at the number of rows (multiple times in a loop). It would be better to get the number of comments as part of the first query: SELECT P.*, COUNT(C.*) AS CmtCount FROM pictures P LEFT JOIN comments C ON P.picid = C.picid WHERE album = $albumid AND status = 'Approved'
  11. something along these lines should work. You just keep capturing a pointer to the element of interest until you have traversed the entire list of keys. $str = 'str1.str2.str3'; $array = array( 'str1' => array( 'str2' => array( 'str3' => 'I want to return this...', ), ), ); $keys = explode ($str, "."); // or is it explode(".", $str)? I can never remember $hold = &$array; foreach ($keys as $key) { $hold = &$hold[$key]; } // $hold now points to the field you are looking for Watchout though. If $str starts out as "str1.str2" you will end up with $hold referencing $array[str1][str2] which is an array NOT a string value.
  12. You can use a session. Open a session in process.php and store the variable there. Just be sure to close the session (session_write_close()) before you send the IMG tag to the browser. If this is the only reason you are using the session, you can destroy it in the image.php (session_destroy()) after you get the value out of it.
  13. Try this: WHERE '2010-02-25 09:36:05' BETWEEN startdate AND enddate
  14. The short answer is No you can't do that. You are closing the form when you output the submit button. However, there is a problem. You are creating a seaparte form for each row in the table: Psuedo Code IF User Is Logged In { IF NO Command was Issued { Select the rows ordered by ID WHILE (For Each Row Selected) { //grab the title and the ID of the enws Start a new DIV Show the Image Start a FORM Start a TABLE Start a ROW (in the Table) Show the ID and Title in separate cells NOTE: If there are multiple rows, they will ALL have the same NAME for the INPUT box End the ROW Show the Thumbnail in a CELL (NOTE you are NOT in a ROW of the TABLE here) Close the TABLE Close The FORM END of WHILE (For Each Row) END of IF NO COMMAND ISSUED START a new DIV SHOW the SUBMIT button CLOSE the FORM (NOTE There is NO FORM open at this point) NOTE: There are two DIVs openned that have NOT been closed IF COMMAND is ORDER { Execute SQL to UPDATE database (NOTE: This query "UPDATE test SET id='$id'" will UPDATE EVERY ROW in the table!!!!) Close the DIV (is there one OPEN here? END IF COMMAND is ORDER END IF User is Logged In ELSE (User is NOT Logged in) Show Login Link END ELSE (User NOT Logged In) You need to do one of two things. 1) Put the SUBMIT button inside the form (in a CELL in the TABLE) in the WHILE loop. This will show multiple Submit buttons and will only allow the user to change one ID at a time. 2) Start the FORM before the WHILE loop; Change the NAME of the ID's input box so you can tell which one is changed. I would use: <input type='text' name='id[$id]' value='$id' size='3'> so the posted data is an array indexed by the OLD ID (the one still in the database) and the value is the NEW ID (what the user wants it changed to). Then you have to change your UPDATE processing to handle the array. Note that this WILL be problematic if the user change (for instance) 3 to 4 and 4 to 3. Having said all that, I have to agree with citricsquid, that this is not the best way to do this. In fact, if ID in your table is AUTO INCREMENT, you can not change the value. You should have a separate column for sequence, and then update the sequence based on the ID. So the input box would look more like this: <input type='text' name='id[$id]' value='$seq' size='3'>
  15. If you add this new column to EVERY table, then you are going to have a problem with JOINs. From your example in the original post: If mid was added to both tables, this new condition is ambiguous and will produce an error. You would have to actually add "AND t1.mid = 1 AND t2.mid = 1". I think you would be better off putting the vendor ID in a session variable and editing all of your queries.
  16. Probably because AUTOPRODUCT is spelled wrong there as well. Also, since there is another place holder ('%s'), you have to pass the product name twice to fill them both in.
  17. Actually, just close PHP, output the HTML, then open PHP again: <?php require_once('common.php'); checkUser(); ?> <?php if ($_SESSION['userName'] == 'Adamriley'){ /* CLOSE PHP HERE BECAUSE WE WANT TO OUTPUT HTML */ ?> <html> <head> <title>adam lee riley</title> </head> <body> </body> </html> <?php }else{ /* OPEN PHP FOR THE ELSE THEN CLOSE IT FOR HTML AGAIN */ ?> <html> <head> <title>Nathan warburton</title> </head> <body> </body> </html> <?php } // OPEN PHP AGAIN FOR THE CLOSING BRACE ?>
  18. It looks like you want the entire row for a particular product that has the lowest price. One way to do this is to select the data sorted by price and only return one row: SELECT * FROM AUTOPODUCT WHERE PNAME = '%s' ORDER BY SALEPRICE LIMIT 1" Another way to do it is using a subquery: SELECT * FROM AUTOPODUCT WHERE PNAME = '%s' AND SALEPRICE = (SELECT MIN(SALEPRICE) FROM AUTOPODUCT WHERE PNAME = '%s')" If you have multiple rows with the same SALEPRICE (which is the lowest for the product) the first method will only return one of them and you will have no way to know that there is another. The second method will return multiple rows and you can test the row count to see if there is more than one with that price.
  19. Actually, I think you want to use htmlspecialchars() to display/edit the file contents in the browser. If you use strip_tags() and store it in the database, you will loose the markup.
  20. try something like this: $days = array('monday', 'tuesday', 'wednesday', 'thursday', 'friday','saturday', 'sunday'); $display_block = ''; foreach ($days as $dow) { $display_block .= "<h1>$dow</h1>"; $get_mon_sql = "SELECT id, name FROM clubs WHERE meet LIKE '%$dow%' ORDER BY name"; $get_mon_res = mysqli_query($mysqli,$get_mon_sql) or die(mysqli_error($mysqli)); while ($mon = mysqli_fetch_array($get_mon_res)) { $id = $mon['id']; $name = ucwords(strtolower(stripslashes($mon['name']))); $display_block .= "<div style=\"text-align: center;\"><a href=\"showitem.php? id=".$id."\">".$name."</a> </div>"; } mysqli_free_result($get_mon_res); }
  21. In this situation, I would build up the where clause in a variable: <?php $where = ''; if (! empty($Wine_Name)) { // using empty() on a value of zero will return true, so if not empty $where .= (empty($where) ? 'WHERE ' : ' AND ') . "WINE.WINE_PROPRIETARY_NAME = '" . mysql_real_escape($Wine_Name) . "'"; // you don't need to keep skipping out and in of PHP so just loose these two lines (below) ?> <?php if (! empty($Vintage)) $where .= (empty($where) ? 'WHERE ' : ' AND ') . "WINE.WINE_VINTAGE = '" . mysql_real_escape($Vintage) . "'"; // ... and so on for all of the others // ... // ... // where are you outside of php here? // anyway, just stick the $where variable into the query ... $sql = "SELECT WINE.WINE_IMAGE_LABEL, WINE.WINE_IMAGE_BOTTLE, WINE.WINE_PROPRIETARY_NAME, WINE.WINE_VINTAGE, WINE.WINE_ALCOHOL_CONTENT, WINE.WINE_PRICE_RANGE, WINE.WINE_UPC, VINEYARD.VINEYARD_DESCRIPTION, VARIETAL_TYPE.VARIETAL_TYPE_DESCRIPTION, TASTING_NOTE.TASTING_NOTE_TEXT, TASTING_NOTE.TASTING_NOTE_DATE, PRODUCER.PRODUCERS_DESCRIPTION, APPELLATION.APPELLATION_DESCRIPTION FROM WINE LEFT JOIN APPELLATION ON WINE.APPELLATION_ID = APPELLATION.APPELLATION_ID LEFT JOIN PRODUCER ON WINE.PRODUCER_ID = PRODUCER.PRODUCER_ID LEFT JOIN VINEYARD ON WINE.VINEYARD_ID = VINEYARD.VINEYARD_ID LEFT JOIN VARIETAL_TYPE ON WINE.VARIETAL_TYPE_ID = VARIETAL_TYPE.VARIETAL_TYPE_ID LEFT JOIN TASTING_NOTE ON WINE.WINE_ID = TASTING_NOTE.WINE_ID LEFT JOIN RATING ON TASTING_NOTE.RATING_ID = RATING.RATING_ID " . $where . " ORDER BY WINE.WINE_ID"; This is just a cut-and-paste example. It has not been tested. But I would build up the where clause this way; you don't have to worry about the value of any field the user did not restrict, and you are not doing unnecessary test at the server.
  22. You need to look at z-index for the DIV's. I had this problem trying to overlay a DIV with a login form on my page header DIV. It turned out the DIV with the login was "underneath" the header so I could not click on it. Give the DIV with the login a higher z-index to bring it up to the "top". <DIV STYLE="position:absolute; top:5px; right:20px; z-index: 3"> I'm no expert with CSS and STYLES, so you may have to play with it. I think I also gave my page header DIV a z-index of -1 (negative one). I think the table is causing a problem because you put it "on top" of the form. Think of the DIV's as index cards, you put one on the table, then put one on top of it. You can't write on the first one because the second one is covering it. Hope that helps.
  23. It means you referred to an element of an array but the element does not exist. Such as: $test[0] = 'Line 0'; $test[1] = 'Line 1'; // The following line produces a notice, because we did not define element 2 print $test[2]; "on line 0" -- I'm not sure why it says line zero. Are you using eval or annonymous functions? Without seeing some code, we can't really help identify the problem.
  24. Can you post your code with the changes you have made? Also, post any error messages that you get.
  25. You can't always leave a column out of the update statement. If there is currently a value in the database and the user (or the process) decides that it needs to be removed, then you have to set the column to NULL. I don't know who decided that putting invalid data in the database (meaning a zero date) is better than throwing an error when a date is out of range, but IMHO it is a very bad idea. The database is "doing us a favor" by allowing an insert or update to run, but we get stuck with data that is not valid. So, instead of "SELECT * FROM schedule WHERE date IS NULL" we have to use "SELECT * FROM schedule WHERE date IS NULL OR Date = 0" (Note that you can't select where Date = '' (empty string) even though that was the way it was input). From most of the code I've seen here, people like to have their SQL "pre-built" and just fill in the blanks. Some use sprintf(), most seem to use the style our OP did here (UPDATE Table SET column1 = '$var1', column2 = '$var2' ...). I've generally avoided both approaches, because: a) I don't like putting variables inside a string, it just feels wrong. (I know that is a great feature of PHP, but I avoid it;) and b) it makes it impossible to set a value to NULL, the best you can get is an empty string. (Which is invalid for a date, and is why we are in this topic in the first place). In the database world, NULL has a completely different meaning from an empty string (or zero'd integer). NULL means there is no value (or we don't know the value); and an empty string means the value is known, it is nothing. Sometimes you need a NULL. The code (I suggested) is not pretty, but it provides a wordaround to the problem of the database "truncating" an invalid value and inserting something other than what was provided. A better solution would be: $sql = 'UPDATE table ' . 'SET Service=' . (empty($Service) ? 'NULL' : "'$Service'), " . 'Provider=' . (empty($provider) ? 'NULL' : "'$provider'," . 'Date=' . (empty($date) ? 'NULL' : "'$date' " . "WHERE id = '$id '; " which I accomplish using a couple of home-grown functions: $sql = 'UPDATE table ' . 'SET Service=' . quoteString($Service) . ', ' . 'Provider=' . quoteString($provider) . ', ' . 'Date=' . quoteStringNull($date) . ' ' . "WHERE id = '$id '; " quoteString() returns the supplied value, escaped and enclosed in single quotes. quoteStringNull does the same thing, except if the string is empty it returns the string NULL without the single quotes.
×
×
  • 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.