Fossil SCM

In /ainfo elide the content if it's pending moderation and the user lacks permission to moderate or delete it. It's possible for unprivileged users to bypass this restriction by passing the same hash to /artifact, which will reveal the content.

stephan 2026-05-24 12:28 UTC forum-attachments
Commit 641e7fced175b7e1d7fd17e3b3e432a632112d605fed5ec388b3c8deb5a8f308
1 file changed +30 -26
+30 -26
--- src/attach.c
+++ src/attach.c
@@ -740,46 +740,50 @@
740740
if( modPending && (isModerator || bUserIsOwner) ){
741741
@ <div class="section">Moderation</div>
742742
@ <blockquote>
743743
form_begin(0, "%R/ainfo/%s", zUuid);
744744
@ <label><input type="radio" name="modaction" value="delete">
745
- @ Delete this change</label><br>
745
+ @ Delete this attachment</label><br>
746746
if( isModerator ){
747747
@ <label><input type="radio" name="modaction" value="approve">
748
- @ Approve this change</label><br>
748
+ @ Approve this attachment</label><br>
749749
}
750750
@ <input type="submit" value="Submit">
751751
login_insert_csrf_secret();
752752
@ </form>
753753
@ </blockquote>
754754
}
755755
756
- @ <div class="section">Content Appended</div>
757
- @ <blockquote>
756
+ @ <div class="section">Content:</div>
758757
blob_zero(&attach);
759
- if( fShowContent ){
760
- const char *z;
761
- content_get(ridSrc, &attach);
762
- blob_to_utf8_no_bom(&attach, 0);
763
- z = blob_str(&attach);
764
- if( zLn ){
765
- output_text_with_line_numbers(z, blob_size(&attach), zName, zLn, 1);
766
- }else{
767
- @ <pre>
768
- @ %h(z)
769
- @ </pre>
770
- }
771
- }else if( strncmp(zMime, "image/", 6)==0 ){
772
- int sz = db_int(0, "SELECT size FROM blob WHERE rid=%d", ridSrc);
773
- @ <i>(file is %d(sz) bytes of image data)</i><br>
774
- @ <img src="%R/raw/%s(zSrc)?m=%s(zMime)"></img>
775
- style_submenu_element("Image", "%R/raw/%s?m=%s", zSrc, zMime);
776
- }else{
777
- int sz = db_int(0, "SELECT size FROM blob WHERE rid=%d", ridSrc);
778
- @ <i>(file is %d(sz) bytes of binary data)</i>
779
- }
780
- @ </blockquote>
758
+ if( modPending && !moderation_user_could(rid, 1, 0) ){
759
+ @ <p><span class="modpending">Content is awaiting moderator approval.</span></p>
760
+ }else{
761
+ @ <blockquote>
762
+ if( fShowContent ){
763
+ const char *z;
764
+ content_get(ridSrc, &attach);
765
+ blob_to_utf8_no_bom(&attach, 0);
766
+ z = blob_str(&attach);
767
+ if( zLn ){
768
+ output_text_with_line_numbers(z, blob_size(&attach), zName, zLn, 1);
769
+ }else{
770
+ @ <pre>
771
+ @ %h(z)
772
+ @ </pre>
773
+ }
774
+ }else if( strncmp(zMime, "image/", 6)==0 ){
775
+ int sz = db_int(0, "SELECT size FROM blob WHERE rid=%d", ridSrc);
776
+ @ <i>(file is %d(sz) bytes of image data)</i><br>
777
+ @ <img src="%R/raw/%s(zSrc)?m=%s(zMime)"></img>
778
+ style_submenu_element("Image", "%R/raw/%s?m=%s", zSrc, zMime);
779
+ }else{
780
+ int sz = db_int(0, "SELECT size FROM blob WHERE rid=%d", ridSrc);
781
+ @ <i>(file is %d(sz) bytes of binary data)</i>
782
+ }
783
+ @ </blockquote>
784
+ }
781785
manifest_destroy(pAttach);
782786
blob_reset(&attach);
783787
style_finish_page();
784788
}
785789
786790
--- src/attach.c
+++ src/attach.c
@@ -740,46 +740,50 @@
740 if( modPending && (isModerator || bUserIsOwner) ){
741 @ <div class="section">Moderation</div>
742 @ <blockquote>
743 form_begin(0, "%R/ainfo/%s", zUuid);
744 @ <label><input type="radio" name="modaction" value="delete">
745 @ Delete this change</label><br>
746 if( isModerator ){
747 @ <label><input type="radio" name="modaction" value="approve">
748 @ Approve this change</label><br>
749 }
750 @ <input type="submit" value="Submit">
751 login_insert_csrf_secret();
752 @ </form>
753 @ </blockquote>
754 }
755
756 @ <div class="section">Content Appended</div>
757 @ <blockquote>
758 blob_zero(&attach);
759 if( fShowContent ){
760 const char *z;
761 content_get(ridSrc, &attach);
762 blob_to_utf8_no_bom(&attach, 0);
763 z = blob_str(&attach);
764 if( zLn ){
765 output_text_with_line_numbers(z, blob_size(&attach), zName, zLn, 1);
766 }else{
767 @ <pre>
768 @ %h(z)
769 @ </pre>
770 }
771 }else if( strncmp(zMime, "image/", 6)==0 ){
772 int sz = db_int(0, "SELECT size FROM blob WHERE rid=%d", ridSrc);
773 @ <i>(file is %d(sz) bytes of image data)</i><br>
774 @ <img src="%R/raw/%s(zSrc)?m=%s(zMime)"></img>
775 style_submenu_element("Image", "%R/raw/%s?m=%s", zSrc, zMime);
776 }else{
777 int sz = db_int(0, "SELECT size FROM blob WHERE rid=%d", ridSrc);
778 @ <i>(file is %d(sz) bytes of binary data)</i>
779 }
780 @ </blockquote>
 
 
 
 
 
781 manifest_destroy(pAttach);
782 blob_reset(&attach);
783 style_finish_page();
784 }
785
786
--- src/attach.c
+++ src/attach.c
@@ -740,46 +740,50 @@
740 if( modPending && (isModerator || bUserIsOwner) ){
741 @ <div class="section">Moderation</div>
742 @ <blockquote>
743 form_begin(0, "%R/ainfo/%s", zUuid);
744 @ <label><input type="radio" name="modaction" value="delete">
745 @ Delete this attachment</label><br>
746 if( isModerator ){
747 @ <label><input type="radio" name="modaction" value="approve">
748 @ Approve this attachment</label><br>
749 }
750 @ <input type="submit" value="Submit">
751 login_insert_csrf_secret();
752 @ </form>
753 @ </blockquote>
754 }
755
756 @ <div class="section">Content:</div>
 
757 blob_zero(&attach);
758 if( modPending && !moderation_user_could(rid, 1, 0) ){
759 @ <p><span class="modpending">Content is awaiting moderator approval.</span></p>
760 }else{
761 @ <blockquote>
762 if( fShowContent ){
763 const char *z;
764 content_get(ridSrc, &attach);
765 blob_to_utf8_no_bom(&attach, 0);
766 z = blob_str(&attach);
767 if( zLn ){
768 output_text_with_line_numbers(z, blob_size(&attach), zName, zLn, 1);
769 }else{
770 @ <pre>
771 @ %h(z)
772 @ </pre>
773 }
774 }else if( strncmp(zMime, "image/", 6)==0 ){
775 int sz = db_int(0, "SELECT size FROM blob WHERE rid=%d", ridSrc);
776 @ <i>(file is %d(sz) bytes of image data)</i><br>
777 @ <img src="%R/raw/%s(zSrc)?m=%s(zMime)"></img>
778 style_submenu_element("Image", "%R/raw/%s?m=%s", zSrc, zMime);
779 }else{
780 int sz = db_int(0, "SELECT size FROM blob WHERE rid=%d", ridSrc);
781 @ <i>(file is %d(sz) bytes of binary data)</i>
782 }
783 @ </blockquote>
784 }
785 manifest_destroy(pAttach);
786 blob_reset(&attach);
787 style_finish_page();
788 }
789
790

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button